paddlepaddle將數據保存為recordio文件並讀取
因為有時候一次性將數據加載到內存中有可能太大,所以我們可以選擇將數據轉換成標准格式recordio文件並讀取供我們的網絡利用,接下來記錄一下如何保存數據為recordio,並讀取。
將數據保存為RecordIO文件
import paddle.fluid as fluid
import numpy
def reader_creator():
def __impl__():
for i in range(1000):
yield [
numpy.random.random(size=[3,224,224], dtype="float32"),
numpy.random.random(size=[1], dtype="int64")
]
return __impl__
img = fluid.layers.data(name="image", shape=[3, 224, 224])
label = fluid.layers.data(name="label", shape=[1], dtype="int64")
feeder = fluid.DataFeeder(feed_list=[img, label], place=fluid.CPUPlace())
BATCH_SIZE = 32
reader = paddle.batch(reader_creator(), batch_size=BATCH_SIZE)
fluid.recordio_writer.convert_reader_to_recordio_file(
"train.recordio", feeder=feeder, reader_creator=reader)
乍看也能看懂,非常合理,但是我這么保存以后就出現問題,在后面的讀取數據的時候,一般我們會把[3,244,244]的圖片送入卷積層,但是會報錯,提示維數至少為4維,這點跟tensorflow一樣,第一維是維數,那么應該怎么辦呢?我的方法是:
def reader_creator():
def __impl__():
for i in range(len(src_im_test)):
yield [
src_im_test[i],#shape=[3,244,244]
test_desmap[i],#shape=[3,244,244]
test_num[i] #shape=[1]
]
return __impl__
img = fluid.layers.data(name="image", shape=[-1,3, 244, 244])#注意這里要加-1
label = fluid.layers.data(name="label", shape=[-1,1,244, 244])
num = fluid.layers.data(name="num", shape=[1], dtype='int64')
feeder = fluid.DataFeeder(feed_list=[img, label, num], place=fluid.CPUPlace())
reader = paddle.batch(reader_creator(), batch_size=1)
fluid.recordio_writer.convert_reader_to_recordio_file(
"train.recordio", feeder=feeder, reader_creator=reader)
這里把batch_size 設為1,后面讀取的時候可以自由組batch_size。
從RecordIO讀取數據傳入網絡
這里是官網代碼:
import paddle.fluid as fluid
file_obj = fluid.layers.open_files(
filenames=["train.recordio"],
shape=[[3, 224, 224], [1]],
lod_levels=[0, 0],
dtypes=["float32", "int64"],
pass_num=100
)
image, label = fluid.layers.read_file(file_obj)
對應於上面的官網例子,但是前面說過,這樣子有問題(在我這里是不能送入卷積層),下面給出我的讀取方法,和上面我的代碼相對應:
import paddle.fluid as fluid
file_obj = fluid.layers.open_files(
filenames=["train.recordio"],
shapes = [[-1,3, 244, 244], [-1,1,244, 244],[-1, 1]],
dtypes=['float32','float32','int64'],
lod_levels=[0, 0, 0],
)
file_obj = fluid.layers.batch(file_obj, batch_size=9)
img, des_im, total_num = fluid.layers.read_file(file_obj)#這里的數據可以直接送入網絡
conv1 = fluid.layers.conv2d(img, 1, 1)#如果前面保存時不指定-1,這里就會報錯
loss =fluid.layers.reduce_mean(fluid.layers.square_error_cost(input=conv1,label=des_im))
exe = fluid.Executor(fluid.CPUPlace())
exe.run(fluid.default_startup_program())
loss_v, = exe.run(fetch_list=[loss])
print "loss is {}".format(loss_v)
這里需要說明的是,從文件里面讀取的數據已經是網絡可以識別的數據格式了,有興趣的話可以fluid.layers.data生成的變量一起print出來看一下,是一樣的類型。
結果:
loss is [190564.94]
注意,返回的是一個numpy array,這里可以修改exe.run里面的參數return_numpy=False來決定。
我們再來看一下:
num = exe.run(fetch_list=[total_num])
print "num is {}".format(num)
結果:
num is [[17]
[13]
[61]
[9]
[8]
[9]
[17]
[29]
[9]]
同樣返回的也是numpy array,可以看出來是怎么組成batch的。