Python通過TensorFlow卷積神經(jīng)網(wǎng)絡(luò)實(shí)現(xiàn)貓狗識別
這份數(shù)據(jù)集來源于Kaggle,數(shù)據(jù)集有12500只貓和12500只狗。在這里簡單介紹下整體思路
- 處理數(shù)據(jù)
- 設(shè)計神經(jīng)網(wǎng)絡(luò)
- 進(jìn)行訓(xùn)練測試
1. 數(shù)據(jù)處理
將圖片數(shù)據(jù)處理為 tf 能夠識別的數(shù)據(jù)格式,并將數(shù)據(jù)設(shè)計批次。
- 第一步
get_files()方法讀取圖片,然后根據(jù)圖片名,添加貓狗 label,然后再將 image和label 放到 數(shù)組中,打亂順序返回 - 將第一步處理好的圖片 和label 數(shù)組 轉(zhuǎn)化為 tensorflow 能夠識別的格式,然后將圖片裁剪和補(bǔ)充進(jìn)行標(biāo)準(zhǔn)化處理,分批次返回。
新建數(shù)據(jù)處理文件 ,文件名 input_data.py
import tensorflow as tf
import os
import numpy as np
def get_files(file_dir):
cats = []
label_cats = []
dogs = []
label_dogs = []
for file in os.listdir(file_dir):
name = file.split(sep='.')
if 'cat' in name[0]:
cats.append(file_dir + file)
label_cats.append(0)
else:
if 'dog' in name[0]:
dogs.append(file_dir + file)
label_dogs.append(1)
image_list = np.hstack((cats,dogs))
label_list = np.hstack((label_cats,label_dogs))
# print('There are %d cats\nThere are %d dogs' %(len(cats), len(dogs)))
# 多個種類分別的時候需要把多個種類放在一起,打亂順序,這里不需要
# 把標(biāo)簽和圖片都放倒一個 temp 中 然后打亂順序,然后取出來
temp = np.array([image_list,label_list])
temp = temp.transpose()
# 打亂順序
np.random.shuffle(temp)
# 取出第一個元素作為 image 第二個元素作為 label
image_list = list(temp[:,0])
label_list = list(temp[:,1])
label_list = [int(i) for i in label_list]
return image_list,label_list
# 測試 get_files
# imgs , label = get_files('/Users/yangyibo/GitWork/pythonLean/AI/貓狗識別/testImg/')
# for i in imgs:
# print("img:",i)
# for i in label:
# print('label:',i)
# 測試 get_files end
# image_W ,image_H 指定圖片大小,batch_size 每批讀取的個數(shù) ,capacity隊列中 最多容納元素的個數(shù)
def get_batch(image,label,image_W,image_H,batch_size,capacity):
# 轉(zhuǎn)換數(shù)據(jù)為 ts 能識別的格式
image = tf.cast(image,tf.string)
label = tf.cast(label, tf.int32)
# 將image 和 label 放倒隊列里
input_queue = tf.train.slice_input_producer([image,label])
label = input_queue[1]
# 讀取圖片的全部信息
image_contents = tf.read_file(input_queue[0])
# 把圖片解碼,channels =3 為彩色圖片, r,g ,b 黑白圖片為 1 ,也可以理解為圖片的厚度
image = tf.image.decode_jpeg(image_contents,channels =3)
# 將圖片以圖片中心進(jìn)行裁剪或者擴(kuò)充為 指定的image_W,image_H
image = tf.image.resize_image_with_crop_or_pad(image, image_W, image_H)
# 對數(shù)據(jù)進(jìn)行標(biāo)準(zhǔn)化,標(biāo)準(zhǔn)化,就是減去它的均值,除以他的方差
image = tf.image.per_image_standardization(image)
# 生成批次 num_threads 有多少個線程根據(jù)電腦配置設(shè)置 capacity 隊列中 最多容納圖片的個數(shù) tf.train.shuffle_batch 打亂順序,
image_batch, label_batch = tf.train.batch([image, label],batch_size = batch_size, num_threads = 64, capacity = capacity)
# 重新定義下 label_batch 的形狀
label_batch = tf.reshape(label_batch , [batch_size])
# 轉(zhuǎn)化圖片
image_batch = tf.cast(image_batch,tf.float32)
return image_batch, label_batch
# test get_batch
# import matplotlib.pyplot as plt
# BATCH_SIZE = 2
# CAPACITY = 256
# IMG_W = 208
# IMG_H = 208
# train_dir = '/Users/yangyibo/GitWork/pythonLean/AI/貓狗識別/testImg/'
# image_list, label_list = get_files(train_dir)
# image_batch, label_batch = get_batch(image_list, label_list, IMG_W, IMG_H, BATCH_SIZE, CAPACITY)
# with tf.Session() as sess:
# i = 0
# # Coordinator 和 start_queue_runners 監(jiān)控 queue 的狀態(tài),不停的入隊出隊
# coord = tf.train.Coordinator()
# threads = tf.train.start_queue_runners(coord=coord)
# # coord.should_stop() 返回 true 時也就是 數(shù)據(jù)讀完了應(yīng)該調(diào)用 coord.request_stop()
# try:
# while not coord.should_stop() and i<1:
# # 測試一個步
# img, label = sess.run([image_batch, label_batch])
# for j in np.arange(BATCH_SIZE):
# print('label: %d' %label[j])
# # 因?yàn)槭莻€4D 的數(shù)據(jù)所以第一個為 索引 其他的為冒號就行了
# plt.imshow(img[j,:,:,:])
# plt.show()
# i+=1
# # 隊列中沒有數(shù)據(jù)
# except tf.errors.OutOfRangeError:
# print('done!')
# finally:
# coord.request_stop()
# coord.join(threads)
# sess.close()
2. 設(shè)計神經(jīng)網(wǎng)絡(luò)
利用卷積神經(jīng)網(wǎng)路處理,網(wǎng)絡(luò)結(jié)構(gòu)為
# conv1 卷積層 1 # pooling1_lrn 池化層 1 # conv2 卷積層 2 # pooling2_lrn 池化層 2 # local3 全連接層 1 # local4 全連接層 2 # softmax 全連接層 3
新建神經(jīng)網(wǎng)絡(luò)文件 ,文件名 model.py
#coding=utf-8
import tensorflow as tf
def inference(images, batch_size, n_classes):
with tf.variable_scope('conv1') as scope:
# 卷積盒的為 3*3 的卷積盒,圖片厚度是3,輸出是16個featuremap
weights = tf.get_variable('weights',
shape=[3, 3, 3, 16],
dtype=tf.float32,
initializer=tf.truncated_normal_initializer(stddev=0.1, dtype=tf.float32))
biases = tf.get_variable('biases',
shape=[16],
dtype=tf.float32,
initializer=tf.constant_initializer(0.1))
conv = tf.nn.conv2d(images, weights, strides=[1, 1, 1, 1], padding='SAME')
pre_activation = tf.nn.bias_add(conv, biases)
conv1 = tf.nn.relu(pre_activation, name=scope.name)
with tf.variable_scope('pooling1_lrn') as scope:
pool1 = tf.nn.max_pool(conv1, ksize=[1, 3, 3, 1], strides=[1, 2, 2, 1], padding='SAME', name='pooling1')
norm1 = tf.nn.lrn(pool1, depth_radius=4, bias=1.0, alpha=0.001 / 9.0, beta=0.75, name='norm1')
with tf.variable_scope('conv2') as scope:
weights = tf.get_variable('weights',
shape=[3, 3, 16, 16],
dtype=tf.float32,
initializer=tf.truncated_normal_initializer(stddev=0.1, dtype=tf.float32))
biases = tf.get_variable('biases',
shape=[16],
dtype=tf.float32,
initializer=tf.constant_initializer(0.1))
conv = tf.nn.conv2d(norm1, weights, strides=[1, 1, 1, 1], padding='SAME')
pre_activation = tf.nn.bias_add(conv, biases)
conv2 = tf.nn.relu(pre_activation, name='conv2')
# pool2 and norm2
with tf.variable_scope('pooling2_lrn') as scope:
norm2 = tf.nn.lrn(conv2, depth_radius=4, bias=1.0, alpha=0.001 / 9.0, beta=0.75, name='norm2')
pool2 = tf.nn.max_pool(norm2, ksize=[1, 3, 3, 1], strides=[1, 1, 1, 1], padding='SAME', name='pooling2')
with tf.variable_scope('local3') as scope:
reshape = tf.reshape(pool2, shape=[batch_size, -1])
dim = reshape.get_shape()[1].value
weights = tf.get_variable('weights',
shape=[dim, 128],
dtype=tf.float32,
initializer=tf.truncated_normal_initializer(stddev=0.005, dtype=tf.float32))
biases = tf.get_variable('biases',
shape=[128],
dtype=tf.float32,
initializer=tf.constant_initializer(0.1))
local3 = tf.nn.relu(tf.matmul(reshape, weights) + biases, name=scope.name)
# local4
with tf.variable_scope('local4') as scope:
weights = tf.get_variable('weights',
shape=[128, 128],
dtype=tf.float32,
initializer=tf.truncated_normal_initializer(stddev=0.005, dtype=tf.float32))
biases = tf.get_variable('biases',
shape=[128],
dtype=tf.float32,
initializer=tf.constant_initializer(0.1))
local4 = tf.nn.relu(tf.matmul(local3, weights) + biases, name='local4')
# softmax
with tf.variable_scope('softmax_linear') as scope:
weights = tf.get_variable('softmax_linear',
shape=[128, n_classes],
dtype=tf.float32,
initializer=tf.truncated_normal_initializer(stddev=0.005, dtype=tf.float32))
biases = tf.get_variable('biases',
shape=[n_classes],
dtype=tf.float32,
initializer=tf.constant_initializer(0.1))
softmax_linear = tf.add(tf.matmul(local4, weights), biases, name='softmax_linear')
return softmax_linear
def losses(logits, labels):
with tf.variable_scope('loss') as scope:
cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits \
(logits=logits, labels=labels, name='xentropy_per_example')
loss = tf.reduce_mean(cross_entropy, name='loss')
tf.summary.scalar(scope.name + '/loss', loss)
return loss
def trainning(loss, learning_rate):
with tf.name_scope('optimizer'):
optimizer = tf.train.AdamOptimizer(learning_rate= learning_rate)
global_step = tf.Variable(0, name='global_step', trainable=False)
train_op = optimizer.minimize(loss, global_step= global_step)
return train_op
def evaluation(logits, labels):
with tf.variable_scope('accuracy') as scope:
correct = tf.nn.in_top_k(logits, labels, 1)
correct = tf.cast(correct, tf.float16)
accuracy = tf.reduce_mean(correct)
tf.summary.scalar(scope.name + '/accuracy', accuracy)
return accuracy
3. 訓(xùn)練數(shù)據(jù),并將訓(xùn)練的模型存儲
import os
import numpy as np
import tensorflow as tf
import input_data
import model
N_CLASSES = 2 # 2個輸出神經(jīng)元,[1,0] 或者 [0,1]貓和狗的概率
IMG_W = 208 # 重新定義圖片的大小,圖片如果過大則訓(xùn)練比較慢
IMG_H = 208
BATCH_SIZE = 32 #每批數(shù)據(jù)的大小
CAPACITY = 256
MAX_STEP = 15000 # 訓(xùn)練的步數(shù),應(yīng)當(dāng) >= 10000
learning_rate = 0.0001 # 學(xué)習(xí)率,建議剛開始的 learning_rate <= 0.0001
def run_training():
# 數(shù)據(jù)集
train_dir = '/Users/yangyibo/GitWork/pythonLean/AI/貓狗識別/img/' #My dir--20170727-csq
#logs_train_dir 存放訓(xùn)練模型的過程的數(shù)據(jù),在tensorboard 中查看
logs_train_dir = '/Users/yangyibo/GitWork/pythonLean/AI/貓狗識別/saveNet/'
# 獲取圖片和標(biāo)簽集
train, train_label = input_data.get_files(train_dir)
# 生成批次
train_batch, train_label_batch = input_data.get_batch(train,
train_label,
IMG_W,
IMG_H,
BATCH_SIZE,
CAPACITY)
# 進(jìn)入模型
train_logits = model.inference(train_batch, BATCH_SIZE, N_CLASSES)
# 獲取 loss
train_loss = model.losses(train_logits, train_label_batch)
# 訓(xùn)練
train_op = model.trainning(train_loss, learning_rate)
# 獲取準(zhǔn)確率
train__acc = model.evaluation(train_logits, train_label_batch)
# 合并 summary
summary_op = tf.summary.merge_all()
sess = tf.Session()
# 保存summary
train_writer = tf.summary.FileWriter(logs_train_dir, sess.graph)
saver = tf.train.Saver()
sess.run(tf.global_variables_initializer())
coord = tf.train.Coordinator()
threads = tf.train.start_queue_runners(sess=sess, coord=coord)
try:
for step in np.arange(MAX_STEP):
if coord.should_stop():
break
_, tra_loss, tra_acc = sess.run([train_op, train_loss, train__acc])
if step % 50 == 0:
print('Step %d, train loss = %.2f, train accuracy = %.2f%%' %(step, tra_loss, tra_acc*100.0))
summary_str = sess.run(summary_op)
train_writer.add_summary(summary_str, step)
if step % 2000 == 0 or (step + 1) == MAX_STEP:
# 每隔2000步保存一下模型,模型保存在 checkpoint_path 中
checkpoint_path = os.path.join(logs_train_dir, 'model.ckpt')
saver.save(sess, checkpoint_path, global_step=step)
except tf.errors.OutOfRangeError:
print('Done training -- epoch limit reached')
finally:
coord.request_stop()
coord.join(threads)
sess.close()
# train
run_training()
關(guān)于保存的模型怎么使用將在下一篇文章中展示。
TensorFlow 卷積神經(jīng)網(wǎng)絡(luò)之使用訓(xùn)練好的模型識別貓狗圖片
如果需要訓(xùn)練數(shù)據(jù)集可以評論留下聯(lián)系方式。
原文完整代碼地址:
https://github.com/527515025/My-TensorFlow-tutorials/tree/master/貓狗識別
歡迎 star 歡迎提問。
總結(jié)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,謝謝大家對腳本之家的支持。如果你想了解更多相關(guān)內(nèi)容請查看下面相關(guān)鏈接
- python機(jī)器學(xué)習(xí)GCN圖卷積神經(jīng)網(wǎng)絡(luò)原理解析
- python人工智能tensorflow構(gòu)建卷積神經(jīng)網(wǎng)絡(luò)CNN
- Python卷積神經(jīng)網(wǎng)絡(luò)圖片分類框架詳解分析
- Python編程pytorch深度卷積神經(jīng)網(wǎng)絡(luò)AlexNet詳解
- Python深度學(xué)習(xí)pytorch卷積神經(jīng)網(wǎng)絡(luò)LeNet
- Python深度學(xué)習(xí)之實(shí)現(xiàn)卷積神經(jīng)網(wǎng)絡(luò)
- Python?CNN卷積神經(jīng)網(wǎng)絡(luò)實(shí)戰(zhàn)教程深入講解
相關(guān)文章
Python實(shí)現(xiàn)動態(tài)繪圖的示例詳解
matplotlib中的animation提供了動態(tài)繪圖功能,這篇文章主要為大家詳細(xì)介紹了Python如何利用matplotlib實(shí)現(xiàn)動態(tài)繪圖,感興趣的可以了解一下2023-05-05
淺析Python中g(shù)lobal和nonlocal關(guān)鍵字的妙用
這篇文章主要來和大家一起深入探討Python中關(guān)鍵詞global和nonlocal的用法,包括詳細(xì)的示例代碼和實(shí)際應(yīng)用場景,感興趣的可以了解下2024-04-04
詳細(xì)聊一聊為什么Python沒有main函數(shù)
相信很多初學(xué)python的人看代碼的時候都會先找一下main()方法,從main往下看,但事實(shí)上python中是沒有你理解中的“main()”方法的,下面這篇文章主要給大家介紹了關(guān)于為什么Python沒有main函數(shù)的相關(guān)資料,需要的朋友可以參考下2023-03-03
django 實(shí)現(xiàn)編寫控制登錄和訪問權(quán)限控制的中間件方法
今天小編就為大家分享一篇django 實(shí)現(xiàn)編寫控制登錄和訪問權(quán)限控制的中間件方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-01-01

