利用tensorflow构建AlexNet模型,实现小数量级的猫狗分类(只有train)
生活随笔
收集整理的這篇文章主要介紹了
利用tensorflow构建AlexNet模型,实现小数量级的猫狗分类(只有train)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
首先看路徑:
data文件夾分為,model文件夾,train文件夾和文件夾,model文件夾存放模型文件,train存放cat和dog的兩個文件夾圖片,
validation和train一樣。config.py存放配置的一些參數,util.py定義AlexNet框架,AlexNet實現模型的訓練,其他沒有用到。
首先在config.py定義配置文件,都是卷積層和全連接層用到的參數,用字典的形式存儲,
代碼如下:
""" 配置文件:定義參數 """ import tensorflow as tf learning_rate=1e-4 training_iers=200 batch_size=50 display_step=5 n_classes=2 n_fc1=4096 n_fc2=2048W_conv={'conv1':tf.Variable(tf.truncated_normal([11,11,3,96],stddev=0.0001)),'conv2': tf.Variable(tf.truncated_normal([5, 5, 96, 256], stddev=0.01)),'conv3': tf.Variable(tf.truncated_normal([3, 3, 256, 384], stddev=0.01)),'conv4': tf.Variable(tf.truncated_normal([3, 3, 384, 384], stddev=0.01)),'conv5': tf.Variable(tf.truncated_normal([3, 3, 384, 256], stddev=0.01)),'fc1': tf.Variable(tf.truncated_normal([6*6*256,n_fc1], stddev=0.1)),'fc2': tf.Variable(tf.truncated_normal([n_fc1, n_fc2], stddev=0.1)),'fc3': tf.Variable(tf.truncated_normal([n_fc2, n_classes], stddev=0.1))} b_conv={'conv1':tf.Variable(tf.constant(0.0,shape=[96],dtype=tf.float32)),'conv2':tf.Variable(tf.constant(0.1,shape=[256],dtype=tf.float32)),'conv3':tf.Variable(tf.constant(0.1,shape=[384],dtype=tf.float32)),'conv4':tf.Variable(tf.constant(0.1,shape=[384],dtype=tf.float32)),'conv5':tf.Variable(tf.constant(0.1,shape=[256],dtype=tf.float32)),'fc1': tf.Variable(tf.constant(0.1,shape=[n_fc1],dtype=tf.float32)),'fc2': tf.Variable(tf.constant(0.1,shape=[n_fc2],dtype=tf.float32)),'fc3': tf.Variable(tf.constant(0.0,shape=[n_classes],dtype=tf.float32))}在util.py定義AlexNet框架
""" 定義 AlexNet框架 """ import os import numpy as np from config import W_conv,b_conv,n_classes,learning_rate import tensorflow as tf """ 構建AlexNet模型 """ """ 對特征圖進行歸一化 采用標準化處理 """ def batch_norm(inputs,is_training,is_conv_out=True,decay=0.999):scale=tf.Variable(tf.ones([inputs.get_shape()[-1]]))beta=tf.Variable(tf.zeros([inputs.get_shape()[-1]]))pop_mean = tf.Variable(tf.zeros([inputs.get_shape()[-1]]),trainable=False)pop_var = tf.Variable(tf.ones([inputs.get_shape()[-1]]),trainable=False)if is_training:if is_conv_out:batch_mean,batch_var=tf.nn.moments(inputs,[0,1,2])else:batch_mean, batch_var =tf.nn.moments(inputs, [0])#滑動平均train_mean=tf.assign(pop_mean,pop_mean*decay+batch_mean*(1-decay))train_var = tf.assign(pop_var, pop_var * decay + batch_var * (1 - decay))with tf.control_dependencies([train_mean,train_var]):return tf.nn.batch_normalization(inputs,batch_mean,batch_var,beta,scale,0.001)else:return tf.nn.batch_normalization(inputs,pop_mean, pop_var, beta, scale, 0.001) def build_cnn(x,y):x_image=tf.reshape(x,[-1,227,227,3])#卷積層1conv1=tf.nn.relu(tf.nn.conv2d(x_image,W_conv['conv1'],strides=[1,4,4,1],padding='VALID')+b_conv['conv1'])conv1=batch_norm(conv1,True)#池化層1pool1=tf.nn.avg_pool(conv1,ksize=[1,3,3,1],strides=[1,2,2,1],padding='VALID')#LRN層1norm1=tf.nn.lrn(pool1,5,bias=1.0,alpha=0.001/9.0,beta=0.75)#卷積層2conv2=tf.nn.relu(tf.nn.conv2d(norm1,W_conv['conv2'],strides=[1,1,1,1],padding='SAME')+b_conv['conv2'])conv2 = batch_norm(conv2, True)#池化層2pool2=tf.nn.avg_pool(conv2,ksize=[1,3,3,1],strides=[1,2,2,1],padding='VALID')#LRN層2norm2=tf.nn.lrn(pool2,5,bias=1.0,alpha=0.001/9.0,beta=0.75)#卷積層3conv3=tf.nn.relu(tf.nn.conv2d(norm2,W_conv['conv3'],strides=[1,1,1,1],padding='SAME')+b_conv['conv3'])conv3 = batch_norm(conv3, True)#卷積層4conv4=tf.nn.relu(tf.nn.conv2d(conv3,W_conv['conv4'],strides=[1,1,1,1],padding='SAME')+b_conv['conv4'])conv4 = batch_norm(conv4, True)#卷積層5conv5=tf.nn.relu(tf.nn.conv2d(conv4,W_conv['conv5'],strides=[1,1,1,1],padding='SAME')+b_conv['conv5'])conv5 = batch_norm(conv5, True)#池化層5pool5=tf.nn.avg_pool(conv5,ksize=[1,3,3,1],strides=[1,2,2,1],padding='VALID')#全連接層1fc1=tf.matmul(tf.reshape(pool5, [-1, 6 * 6 * 256]), W_conv['fc1']) + b_conv['fc1']fc1 = batch_norm(fc1, True,is_conv_out=False)fc1=tf.nn.relu(fc1)fc1=tf.nn.dropout(fc1,0.5)#全連接層2fc2=tf.matmul(fc1, W_conv['fc2']) + b_conv['fc2']fc2 = batch_norm(fc2, True, is_conv_out=False)fc2=tf.nn.relu(fc2)fc2=tf.nn.dropout(fc2,0.5)#全連接層3fc3=tf.matmul(fc2,W_conv['fc3'])+b_conv['fc3']#定義損失loss=tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits_v2(logits=fc3,labels=y))optimizer=tf.train.GradientDescentOptimizer(learning_rate=learning_rate).minimize(loss)#評估模型accuarcy=tf.reduce_mean(tf.cast(tf.equal(tf.argmax(fc3,1),tf.argmax(y,1)),dtype=tf.float32))return loss,optimizer,accuarcy""" 讀取train.tfrecords并返回image和label 這個是已經做好的.tfrecords文件對于太大的不適合 """ def read_and_decode(filename,batch_size):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),#與存儲的類型一致'image':tf.FixedLenFeature([],tf.string)})img=tf.decode_raw(features['image'],tf.uint8)img=tf.reshape(img,shape=[227,227,3])#img = tf.cast(img, dtype=tf.float32) * (1.0 / 128) - 0.5label = tf.cast(features['label'], dtype=tf.int32)img_batch, label_batch = tf.train.shuffle_batch([img, label], batch_size=batch_size,capacity=64, min_after_dequeue=32,num_threads=64)return img_batch,tf.reshape(label_batch,[batch_size]) """ 將圖片的路徑和對應的標簽存儲在list中返回 """ def get_file(dir):images = []temp = []for root,dirs,files in os.walk(dir):for name in files:images.append(os.path.join(root,name))for name in dirs:#以dogs cats文件夾形式讀取temp.append(os.path.join(root,name))labels=[]for one_folder in temp:n_img=len(os.listdir(one_folder))#展開cats或者dogs的圖片letter=one_folder.split('/')[-1]if letter=='cats':labels=np.append(labels,n_img*[0])#np.append拼接 0是cat 1是dogelse:labels=np.append(labels,n_img*[1])#打亂temp=np.array([images,labels])temp=temp.transpose()np.random.shuffle(temp)image_list=list(temp[:,0])label_list=list(temp[:,1])label_list=[int(float(i)) for i in label_list]return image_list,label_list """ 太大的TFrecord數據集占內存,用此方法可將需要數量的圖片轉換成TFrecord即可 """ def get_batch(image_list,label_list,img_width,img_height,batch_size,capacity):image=tf.cast(image_list,dtype=tf.string)label=tf.cast(label_list, dtype=tf.int32)input_queue=tf.train.slice_input_producer([image,label])label=input_queue[1]image_contents=tf.read_file(input_queue[0])image=tf.image.decode_jpeg(image_contents,channels=3)image=tf.image.resize_image_with_crop_or_pad(image,img_width,img_height)image=tf.image.per_image_standardization(image)#將圖片標準化image_batch,label_batch=tf.train.batch([image,label],batch_size=batch_size,num_threads=64,capacity=capacity)label_batch=tf.reshape(label_batch,[batch_size])return image_batch,label_batch """ 實現標簽的one-hot """ # #轉換one-hot def one_hot(label):n_classes=max(label)+1label = np.eye(n_classes)[label.reshape(-1)]return label # 轉換one-hot # def one_hot(labels): # n_samples=len(labels) # n_class=n_samples+1 # onehot_label=np.zeros((n_samples,n_class)) # onehot_label[np.arange(n_samples),labels]=1 # return onehot_label最后在AlexNet.py調用即可
import tensorflow as tf import util import config import time import matplotlib.pyplot as plt """ 直接讀取整個train.tfrecord """ #filename='./data/train/train.tfrecords' #img_batch,label_batch=util.read_and_decode(filename,batch_size=32) """ 按照需求來讀取圖片 """ dir='./data/train' image_list,label_list=util.get_file(dir) img_batch,label_batch=util.get_batch(image_list,label_list,227,227,batch_size=32,capacity=64) x=tf.placeholder(shape=[None,227,227,3],dtype=tf.float32) y=tf.placeholder(shape=[None,config.n_classes],dtype=tf.float32) loss,optimizer,accuarcy=util.build_cnn(x,y) def train(epoch):init=tf.global_variables_initializer()saver = tf.train.Saver()with tf.Session() as sess:sess.run(init)costs=[]start_time=time.time()save_model='./data/model/AlexNetModel.ckpt'train_writer=tf.summary.FileWriter('./log',sess.graph)#啟動線程#coord=tf.train.Coordinator()threads = tf.train.start_queue_runners(sess=sess)for i in range(epoch):image,label=sess.run([img_batch,label_batch])labels = util.one_hot(label)_,cost,train_accuarcy=sess.run([optimizer,loss,accuarcy],feed_dict={x:image,y:labels})print('step={},loss={},train_accuarcy={}'.format(i,cost,train_accuarcy))costs.append(cost)end_time=time.time()print('step={},time={}'.format(i,(end_time-start_time)))print('')print('optimization is finish')saver.save(sess,save_model)print('model save finished')# coord.request_stop()# coord.join(threads)plt.plot(costs)plt.show()plt.xlabel('iter')plt.ylabel('cost') if __name__ == '__main__':train(epoch=50)損失值打印結果:
未加特征處理
加了歸一化處理:明顯損失值得到了減少
?
由于做好的train.TFrecorder數據集太大,后面改成按照所需的數據量轉換成TFrecorder。
總結
以上是生活随笔為你收集整理的利用tensorflow构建AlexNet模型,实现小数量级的猫狗分类(只有train)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ❤ 想知道大厂面试都问什么吗,附最强面试
- 下一篇: opencv图像处理中的一些滤波器+利用