花了三天的時間渔扎,才成功在down下來的tensorflow代碼上跑通了自己的CNN,心累
數(shù)據(jù)輸入
這個問題幾乎占據(jù)了一天半的時間泄朴。不得不說,tensorflow真的是超級超級煩,尤其是對于我們這些初學(xué)者玫锋,官方文檔及其晦澀又沒有例子挠乳,教程上還老拿MNIST和cifar_10這種做好的數(shù)據(jù)集說事权薯,完全不知道圖片該如何輸入姑躲。
后來還是用TFRecords,先把圖片加上標(biāo)簽制作成二進(jìn)制文件盟蚣,使用時再直接用reader讀
下面是官方教程里的原話
標(biāo)準(zhǔn)TensorFlow格式
另一種保存記錄的方法可以允許你講任意的數(shù)據(jù)轉(zhuǎn)換為TensorFlow所支持的格式黍析, 這種方法可以使TensorFlow的數(shù)據(jù)集更容易與網(wǎng)絡(luò)應(yīng)用架構(gòu)相匹配。這種建議的方法就是使用TFRecords文件屎开,TFRecords文件包含了tf.train.Example 協(xié)議內(nèi)存塊(protocol buffer)(協(xié)議內(nèi)存塊包含了字段 Features)阐枣。你可以寫一段代碼獲取你的數(shù)據(jù), 將數(shù)據(jù)填入到Example協(xié)議內(nèi)存塊(protocol buffer)牍戚,將協(xié)議內(nèi)存塊序列化為一個字符串侮繁, 并且通過tf.python_io.TFRecordWriter class寫入到TFRecords文件。tensorflow/g3doc/how_tos/reading_data/convert_to_records.py就是這樣的一個例子如孝。
從TFRecords文件中讀取數(shù)據(jù)宪哩, 可以使用tf.TFRecordReader的tf.parse_single_example解析器。這個parse_single_example操作可以將Example協(xié)議內(nèi)存塊(protocol buffer)解析為張量第晰。 MNIST的例子就使用了convert_to_records 所構(gòu)建的數(shù)據(jù)锁孟。 請參看tensorflow/g3doc/how_tos/reading_data/fully_connected_reader.py, 您也可以將這個例子跟fully_connected_feed的版本加以比較。
茁瘦。品抽。。還是不會用
后來發(fā)現(xiàn)了一篇博客寫的很好甜熔,而且它添加標(biāo)簽的方法也非常巧妙:
http://blog.csdn.net/u012759136/article/details/52232266
然而不知道為啥我用jpg和jpeg的圖片時轉(zhuǎn)換都報錯了圆恤,換成png才可以
數(shù)據(jù)格式問題
好吧,基本上通過tf.train.batch后腔稀,輸入圖片的shape都會轉(zhuǎn)換成(batch_size盆昙,width,height焊虏,channels)淡喜,label是(batch,int),這兩個都是tensor诵闭。
如果我用教程里跑cifar_10的代碼跑炼团,這種格式基本上就可以了,因?yàn)樽詈筝敵龅膌ogits是類似[-1.11,2.32]的格式:
-
cross_entropy=tf.nn.sparse_softmax_cross_entropy_with_logits(logits,labels)
算交叉熵 - 最后評估的時候用
tf.nn.in_top_k(logits,labels,1)
選logits最大的數(shù)的索引和label比較
但是疏尿,如果用教程里跑MNIST的cnn代碼瘟芝,有很多地方要注意
- 數(shù)據(jù)集是feed輸入的,feed的數(shù)據(jù)格式是有要求的
The value of a feed cannot be a tf.Tensor object. Acceptable feed values include Python scalars, strings, lists, or numpy ndarrays
解決:img,label = sess.run[img,label]
,用返回值 -
cross_entropy = -tf.reduce_sum(y_*tf.log(y_conv))
算交叉熵润歉,所以label必須轉(zhuǎn)成one-hot向量 - 原代碼通過
batch=mnist.train.next_batch(50)
提供數(shù)據(jù),但是tensorflow里TFRecordReader可以夠記住tfrecord的位置模狭,并且始終能返回下一個,所以不需要自己next_batch
讓他訓(xùn)練
一堆亂七八糟的錯誤踩衩,本來覺得挺坑的嚼鹉,做完了覺得簡直弱智贩汉。∶啵總之匹舞,如果程序一直停留的一個地方,既沒卡线脚,也沒報錯赐稽,那基本上就是數(shù)據(jù)沒輸進(jìn)去。浑侥。好好看下代碼現(xiàn)在run的是什么姊舵,返回值是什么,一步一步減小run的深度寓落,然后看是哪個地方漏了什么括丁,TFRecords是不是又不小心修改了,反正我被它坑了好幾次
對了伶选!
如果使用了隊(duì)列史飞,改代碼的時候千萬不能把這一句刪了,不然你什么也看不到仰税,程序又停那了
tf.train.start_queue_runners(sess=sess)
搞了三天构资,真正說的時候覺得也沒什么難的,大概這就是掌握了吧陨簇。吐绵。