1. 程式人生 > >Tensorflow學習教程------實現lenet並且進行二分類

Tensorflow學習教程------實現lenet並且進行二分類

-i ase vector 一個隊列 label ide def shuffle img

#coding:utf-8
import tensorflow as tf
import os
def read_and_decode(filename):
    #根據文件名生成一個隊列
    filename_queue = tf.train.string_input_producer([filename])
    reader = tf.TFRecordReader()
    _, serialized_example = reader.read(filename_queue)   #返回文件名和文件
    features = tf.parse_single_example(serialized_example,
                                       features
={ label: tf.FixedLenFeature([], tf.int64), img_raw : tf.FixedLenFeature([], tf.string), }) img = tf.decode_raw(features[img_raw], tf.uint8) img = tf.reshape(img, [227, 227, 3]) img
= (tf.cast(img, tf.float32) * (1. / 255) - 0.5)*2 label = tf.cast(features[label], tf.int32) print img,label return img, label def get_batch(image, label, batch_size,crop_size): #數據擴充變換 distorted_image = tf.random_crop(image, [crop_size, crop_size, 3])#隨機裁剪 distorted_image = tf.image.random_flip_up_down(distorted_image)#
上下隨機翻轉 distorted_image = tf.image.random_brightness(distorted_image,max_delta=63)#亮度變化 distorted_image = tf.image.random_contrast(distorted_image,lower=0.2, upper=1.8)#對比度變化 #生成batch #shuffle_batch的參數:capacity用於定義shuttle的範圍,如果是對整個訓練數據集,獲取batch,那麽capacity就應該夠大 #保證數據打的足夠亂 images, label_batch = tf.train.shuffle_batch([distorted_image, label],batch_size=batch_size, num_threads=1,capacity=2000,min_after_dequeue=1000) return images, label_batch class network(object): #構造函數初始化 卷積層 全連接層 def lenet(self,images,keep_prob): ‘‘‘ 根據tensorflow中的conv2d函數,我們先定義幾個基本符號 輸入矩陣 W×W,這裏只考慮輸入寬高相等的情況,如果不相等,推導方法一樣,不多解釋。 filter矩陣 F×F,卷積核 stride值 S,步長 輸出寬高為 new_height、new_width 在Tensorflow中對padding定義了兩種取值:VALID、SAME。下面分別就這兩種定義進行解釋說明。 VALID new_height = new_width = (W – F + 1) / S #結果向上取整 SAME new_height = new_width = W / S #結果向上取整 ‘‘‘ images = tf.reshape(images,shape=[-1,28,28,3]) #images = (tf.cast(images,tf.float32)/255.0-0.5)*2 #第一層,卷積層 39,39,3--->5,5,3,32--->39,39,32 #卷積核大小為5*5 輸入層深度為3即三通道圖像 卷積核深度為32即卷積核的個數 conv1_weights = tf.get_variable("conv1_weights",[5,5,3,32],initializer = tf.truncated_normal_initializer(stddev=0.1)) conv1_biases = tf.get_variable("conv1_biases",[32],initializer = tf.constant_initializer(0.0)) #移動步長為1 使用全0填充 conv1 = tf.nn.conv2d(images,conv1_weights,strides=[1,1,1,1],padding=SAME) #激活函數Relu去線性化 relu1 = tf.nn.relu(tf.nn.bias_add(conv1,conv1_biases)) #第二層 最大池化層 39,39,32--->1,2,2,1--->19,19,32 #池化層過濾器大小為2*2 移動步長為2 使用全0填充 pool1 = tf.nn.max_pool(relu1, ksize=[1,2,2,1],strides=[1,2,2,1],padding=SAME) #第三層 卷積層 19,19,32--->5,5,32,64--->19,19,64 #卷積核大小為5*5 當前層深度為32 卷積核的深度為64 conv2_weights = tf.get_variable("conv_weights",[5,5,32,64],initializer = tf.truncated_normal_initializer(stddev=0.1)) conv2_biases = tf.get_variable("conv2_biases",[64],initializer = tf.constant_initializer(0.0)) conv2 = tf.nn.conv2d(pool1,conv2_weights,strides=[1,1,1,1],padding=SAME) #移動步長為1 使用全0填充 relu2 = tf.nn.relu(tf.nn.bias_add(conv2,conv2_biases)) #第四層 最大池化層 19,19,64--->1,2,2,1--->9,9,64 #池化層過濾器大小為2*2 移動步長為2 使用全0填充 pool2 = tf.nn.max_pool(relu2,ksize = [1,2,2,1],strides=[1,2,2,1],padding=SAME) #第五層 全連接層 fc1_weights = tf.get_variable("fc1_weights",[7*7*64,1024],initializer = tf.truncated_normal_initializer(stddev=0.1)) fc1_biases = tf.get_variable("fc1_biases",[1024],initializer = tf.constant_initializer(0.1)) #[1,1024] pool2_vector = tf.reshape(pool2,[-1,7*7*64]) #特征向量扁平化 原始的每一張圖變成了一行9×9*64列的向量 fc1 = tf.nn.relu(tf.matmul(pool2_vector,fc1_weights)+fc1_biases) #為了減少過擬合 加入dropout層 fc1_dropout = tf.nn.dropout(fc1,keep_prob) #第六層 全連接層 #神經元節點數為1024 分類節點2 fc2_weights = tf.get_variable("fc2_weights",[1024,2],initializer=tf.truncated_normal_initializer(stddev=0.1)) fc2_biases = tf.get_variable("fc2_biases",[2],initializer = tf.constant_initializer(0.1)) fc2 = tf.matmul(fc1_dropout,fc2_weights) + fc2_biases return fc2 def lenet_loss(self,fc2,y_): #第七層 輸出層 #softmax y_conv = tf.nn.softmax(fc2) labels=tf.one_hot(y_,2) #定義交叉熵損失函數 #cross_entropy = tf.reduce_mean(-tf.reduce_sum(y_ * tf.log(y_conv),reduction_indices=[1])) loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits = y_conv, labels =labels)) self.cost = loss return self.cost def lenet_optimer(self,loss): train_optimizer = tf.train.GradientDescentOptimizer(lr).minimize(loss) return train_optimizer #計算softmax交叉熵損失函數 def softmax_loss(self,predicts,labels): predicts=tf.nn.softmax(predicts) labels=tf.one_hot(labels,self.weights[fc2].get_shape().as_list()[1]) loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits = predicts, labels =labels)) self.cost= loss return self.cost #梯度下降 def optimer(self,loss,lr=0.01): train_optimizer = tf.train.GradientDescentOptimizer(lr).minimize(loss) return train_optimizer def train(): image,label=read_and_decode("./train.tfrecords") batch_image,batch_label=get_batch(image,label,batch_size=30,crop_size=28) #建立網絡,訓練所用 x = tf.placeholder("float",shape=[None,28,28,3],name=x-input) y_ = tf.placeholder("int32",shape=[None]) keep_prob = tf.placeholder(tf.float32) net=network() inf = net.lenet(x,keep_prob) loss=net.lenet_loss(inf,y_) #計算loss opti=net.optimer(loss) #梯度下降 correct_prediction = tf.equal(tf.cast(tf.argmax(inf,1),tf.int32),batch_label) accuracy = tf.reduce_mean(tf.cast(correct_prediction,tf.float32)) init=tf.global_variables_initializer() with tf.Session() as session: with tf.device("/gpu:0"): session.run(init) coord = tf.train.Coordinator() threads = tf.train.start_queue_runners(coord=coord) max_iter=10000 iter=0 if os.path.exists(os.path.join("model",model.ckpt)) is True: tf.train.Saver(max_to_keep=None).restore(session, os.path.join("model",model.ckpt)) while iter<max_iter: #loss_np,_,label_np,image_np,inf_np=session.run([loss,opti,batch_image,batch_label,inf]) b_batch_image,b_batch_label = session.run([batch_image,batch_label]) loss_np,_=session.run([loss,opti],feed_dict={x:b_batch_image,y_:b_batch_label,keep_prob:0.6}) if iter%50==0: print trainloss:,loss_np if iter%500==0: #accuracy_np = session.run([accuracy]) accuracy_np = session.run([accuracy],feed_dict={x:b_batch_image,y_:b_batch_label,keep_prob:1.0}) print xxxxxxxxxxxxxxxxxxxxxx,accuracy_np iter+=1 coord.request_stop()#queue需要關閉,否則報錯 coord.join(threads) if __name__ == __main__: train()

Tensorflow學習教程------實現lenet並且進行二分類