TfRecord+inception-v3训练图像

最近在使用inception-v3训练模型时遇到了一个问题,由于数据直接是从tfrecord读入,而之前参考的inception-v3的使用代码中,是直接用gfile.FastGFile(image_path,'rb').read()来直接读入jpg文件。所以不符合自己的需求,于是我参考了资料之后,对inception-v3的使用做了改动。

    with gfile.FastGFile(os.path.join(MODEL_DIR,MODEL_FILE),'rb') as f:
        graph_def=tf.GraphDef()
        graph_def.ParseFromString(f.read())
    #加载读取的Inception-v3模型,并返回数据输入所对应的张量以及计算瓶颈层
    #结果所对应的张量
    bottleneck_tensor,jpeg_data_tensor=tf.import_graph_def(
            graph_def,
            return_elements=[BOTTLENECK_TENSOR_NAME,JPEG_DATA_TENSOR_NAME])

在上面的使用代码中,涉及到两个配置选项,一个是BOTTLENECK_TENSOR_NAME,它是Inception-v3中代表瓶颈层结果的张量名称。在谷歌提供的Inception-v3模型中,

这个张量名称就是‘pool_3/reshape:0’,一个是JPEG_DATA_TENSOR_NAME,是图像输入张量所对应的名称,在之前参考的代码中,由于是直接读入jpg文件,它的写法是DecodeJpeg/contents:0。在查阅资料后,发现inception支持

(1)DecodeJpeg/contents --raw image data

(2)DecodeJpeg --uint8 image [h,w,channels=3]

(3)Cast --uint8->float32

(4)ExpandDims --add dimention[1,h,w,channels]

(5)ExpandDims/dim

(6)ResizeBilinear/size --299 x 299

(7)ResizeBilinear --resize image to 299 x 299

(8)Sub/y

(9)Sub -- -128 -normalize

(10)Mul/y (11)Mul -- /128 -normalize。所以在将JPEG_DATA_TENSOR_NAME设置为DecodeJpeg:0

后即可直接使用图像矩阵来使用inception。使用inception-v3和tfrecord的训练代码如下:

import os.path
import numpy as np
import tensorflow as tf
from tensorflow.python.platform import gfile

#Inception-v3模型瓶颈层的节点个数
BOTTLENECK_TENSOR_SIZE = 2048

#Inception-v3模型中代表瓶颈层结果的张量名称。在谷歌提供的Inception-v3模型中,这个张量
#名称就是'pool_3/reshape:0'。在训练的模型时,可以通过tensor.name来获取张量的名称。
BOTTLENECK_TENSOR_NAME = ' 0'

#图像输入张量所对应的名臣
JPEG_DATA_TENSOR_NAME='DecodeJpeg:0'

#下载的谷歌训练好的Inception-v3模型文件目录
MODEL_DIR = '/notebooks'

#下载的谷歌训练好的Inception-v3模型文件名
MODEL_FILE = 'tensorflow_inception_graph.pb'

#验证的数据百分比
VALIDATION_PERCENTAGE = 10
#测试的数据百分比
TEST_PERCENTAGE = 10

#定义神经网络的设置
LEARNING_RATE = 0.01
STEPS = 4000
BATCH=100


def read_and_decode(filename_queue,have):
    #创建一个reader来读取TFRecord文件中的样例
    reader = tf.TFRecordReader()
    #从文件中读出一个样例
    _,serialized_example = reader.read(filename_queue)
    #解析读入的一个样例
    if have:
        features = tf.parse_single_example(serialized_example,features={
            'label':tf.FixedLenFeature([],tf.int64),
            'img_raw':tf.FixedLenFeature([],tf.string)
            })
        label = tf.cast(features['label'],tf.int32)
        image = tf.decode_raw(features['img_raw'],tf.uint8)
        image = tf.reshape(image, [128, 128, 3])
        sess=tf.Session()
        coord=tf.train.Coordinator()
        threads= tf.train.start_queue_runners(coord=coord,sess=sess)
        label_list=[]
        image_list=[]
        for i in range(20):
            images,labels=sess.run([image,label])
            image_list.append(images)
            label_list.append(labels)
        coord.request_stop()
        coord.join(threads)
        return image_list,label_list
    else:
        features = tf.parse_single_example(serialized_example,features={
            'img_raw':tf.FixedLenFeature([],tf.string)
            })
        image = tf.decode_raw(features['img_raw'],tf.uint8)
        image = tf.reshape(image, [30, 30, 3])
        sess=tf.Session()
        coord=tf.train.Coordinator()
        threads= tf.train.start_queue_runners(coord=coord,sess=sess)
        label_list=[]
        image_list=[]
        for i in range(85510):
            images,labels=sess.run([image,label])
            image_list.append(images)
            label_list.append(labels)
        coord.request_stop()
        coord.join(threads)
        return image_list,label_list

#这个函数使用加载的训练好的Inception-v3模型处理一张图片,得到这个图片的特征向量。
def run_bottleneck_on_image(sess,image_data,image_data_tensor,bottleneck_tensor):
    bottleneck_values=sess.run(bottleneck_tensor,{image_data_tensor:image_data})
    bottleneck_values=np.squeeze(bottleneck_values)
    return bottleneck_values

#这个函数获取一张图片经过Inception-v3模型处理之后的特征向量。这个函数会先试图寻找
#已经计算且保存下来的特征向量,如果找不到则先计算这个特征向量,然后保存到文件
def get_or_create_bottleneck(
        sess,image_data,jpeg_data_tensor,bottleneck_tensor):
    bottleneck_values=run_bottleneck_on_image(sess,image_data,jpeg_data_tensor,bottleneck_tensor)
    return bottleneck_values

def get_random_cached_bottlenecks(
        sess,image_lists,label_lists,how_many,
        jpeg_data_tensor,bottleneck_tensor):
    bottlenecks=[]
    ground_truths=[]
    i=0;
    for img in image_lists:  
        label_name=label_lists[i]
        i=i+1
        bottleneck=get_or_create_bottleneck(
                    sess,img,
                    jpeg_data_tensor,bottleneck_tensor)
        ground_truth=np.zeros(2,dtype=np.float32)
        if label_name==1:
            ground_truth[0]=1.0
        else:
            ground_truth[1]=1.0
        bottlenecks.append(bottleneck)
        ground_truths.append(ground_truth)
    return bottlenecks,ground_truths


def main(_):
    print os.path.join(MODEL_DIR,MODEL_FILE)
    with gfile.FastGFile(os.path.join(MODEL_DIR,MODEL_FILE),'rb') as f:
        graph_def=tf.GraphDef()
        graph_def.ParseFromString(f.read())
    #加载读取的Inception-v3模型,并返回数据输入所对应的张量以及计算瓶颈层
    #结果所对应的张量
    bottleneck_tensor,jpeg_data_tensor=tf.import_graph_def(
            graph_def,
            return_elements=[BOTTLENECK_TENSOR_NAME,JPEG_DATA_TENSOR_NAME])
    
    #定义一层全链接层来解决新的图像分类问题。因为训练好的Inception-v3模型已经将原始
    #的图片抽象为了更加容易分类的特征向量了,所以不需要再训练那么复杂的神经网络来完成
    #这个新的分类任务
    bottleneck_input=tf.placeholder(
            tf.float32,[None,BOTTLENECK_TENSOR_SIZE],
            name='BottleneckInputPlaceholder')
    #定义新的标准答案输入
    ground_truth_input=tf.placeholder(
            tf.float32,[None,2],name='GroundTruthInput')
    #定义一层全链接层来解决新的图片分类问题。因为训练好的Inception-v3模型已经将原始
    #的图片抽象为了更加容易分类的特征向量了,所以不需要再训练那么复杂的神经网络来完成
    #这个新的分类任务
    with tf.name_scope('final_training_ops'):
        weights=tf.Variable(tf.truncated_normal(
            [BOTTLENECK_TENSOR_SIZE,2],stddev=0.001))
        biases=tf.Variable(tf.zeros([2]))
        logits=tf.matmul(bottleneck_input,weights)+biases
        final_tensor=tf.nn.softmax(logits)
    
    #定义交叉熵损失函数
    cross_entropy=tf.nn.softmax_cross_entropy_with_logits(
            logits=logits,labels=ground_truth_input)
    cross_entropy_mean=tf.reduce_mean(cross_entropy)
    train_step=tf.train.GradientDescentOptimizer(LEARNING_RATE).minimize(cross_entropy_mean)
    
        
    with tf.Session() as sess:
        init=tf.global_variables_initializer()
        sess.run(init)
        print '读数据'
        image_list=[]
        label_list=[]
        print '训练开始'
        #训练过程
        filename_queue1=tf.train.string_input_producer(["out/output.tfrecords"])
        image_list1, label_list1=read_and_decode(filename_queue1,True)
        for i in range(STEPS):
            #每次获取一个batch的训练数据
            if i%100==0:
                print i
            train_bottlenecks,train_ground_truth=get_random_cached_bottlenecks(
                        sess,image_list1,label_list1,BATCH,jpeg_data_tensor,bottleneck_tensor)
            sess.run(train_step,
                    feed_dict={bottleneck_input:train_bottlenecks,
                              ground_truth_input:train_ground_truth})
        print '训练结束'
        filename_queue2=tf.train.string_input_producer(["out/output2015.tfrecords"])
        image_list2=read_and_decode(filename_queue2,False)
 
        bottlenecks=[]
        rows=170
        column=503
        i=0
        for image_data in image_list2:
            bottleneck_values=run_bottleneck_on_image(sess,image_data,jpeg_data_tensor,bottleneck_tensor)
            bottlenecks.append(bottleneck_values)
            final=sess.run(final_tensor,feed_dict={bottleneck_input:bottlenecks})
            bottlenecks=[]
            np.savetxt('/notebooks/result_2015/result_2015_'+str(i/column)+'_'+str(i%column)+'.txt',final,fmt='%.2f')
               
                 
                
if __name__=='__main__':
    tf.app.run() 
     
  





评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值