学完了tensor flow课程,才发现刚刚入门。对于python语法、常用工具、常用库、IDE都不熟悉。本文旨在记录一些基本的操作,并对源代码进行注释。
课程:http://edu.csdn.net/course/detail/5222
源码:https://github.com/DeepVisionTeam/Dogs_vs_Cats.git
关于这个例子:猫狗识别。
例子的说明:https://github.com/DeepVisionTeam/Dogs_vs_Cats/tree/master/notebook
用Jupyter打开。
1 数据下载
https://www.kaggle.com/c/dogs-vs-cats/data
2个zip文件和一个csv文件。其中train.zip是训练集,训练集中的文件名包含了标签信息,test1.zip是测试集,测试集的标签信息(正确答案)存在sampleSubmission.csv
2 解压
在源码中找到train.py所在的目录,新建文件夹images,将train.zip中的文件全部解压出来。
3 运行Anaconda Prompt,如果有多个python环境,切换到tensor flow所用的环境,例如执行, tensorflow是环境名。
activate tensorflow
4 执行训练
python train.py
加载图片的时候报可能会报内存不足的错误,是因为本例为了简化,会把所有的样本读取到内存中。解决方法是删除images文件夹中的一些样本。
5 测试
python prdiect.py
# filename: train.py
# glob是用来查找匹配的文件的
import glob
import os
# 使用到了tflean和sklearn,train_test_split用来分隔训练集和样本集
import tflearn
from sklearn.model_selection import train_test_split
# image_utils 是自定义的python源文件,preprocess_image用来对图片进行预处理
from image_utils import preprocess_image
# os.path.join()用于拼接多个路径,区别于string.join()
# __file__是个相对路径,以`python train.py`运行本文件时,__file__为空
pjoin = os.path.join
TRAIN_DATA = pjoin(os.path.dirname(__file__), 'images')
MODEL_PATH = pjoin(os.path.dirname(__file__), 'model')
# 如果model文件夹不存在,则创建它
# if not os.path.exists(MODEL_PATH):
# os.makedirs(MODEL_PATH, mode=0755)
MODEL_NAME = 'resnet_dogs_vs_cats.model'
# 改函数读取images目录中的jpg图片,缩放成256*256*3通道
# 返回2个tuple,tuple中的元素都是list。
# X是训练数据,y是训练数据的标签(分类)
def read_data():
X = []
Y = []
# glob.glob()匹配当前所有满足条件的文件名,返回一个List, 例如:['images\\cat.0.jpg', 'images\\cat.1.jpg', 'images\\dog.0.jpg', 'images\\dog.1.jpg']
for f in glob.glob(TRAIN_DATA + '/*.jpg'):
# os.path.basename 取得不带路径的文件名,例如cat.0.jpg
fname = os.path.basename(f)
# 如果文件名以cat开头,标签设为0,否则为1
label = 0 if fname.startswith('cat') else 1
#读取图片文件并进行预处理。
image = preprocess_image(f, [256, 256, 3])
# 把 image,lable 分别附加到训练集的list中
X.append(image)
Y.append(label)
# 随机分割训练集和测试集,输入的X和Y都是List,与具体类型无关。
# test_size表示测试集所占的比例,random_state是随机数种子,可以忽略
X, X_test, y, y_test = train_test_split(X, Y,
test_size=0.2,
random_state=42)
return (X, y), (X_test, y_test)
# 构建残差网络ResNet,返回net
def resnet():
# Residual blocks
n = 5
# Building Residual Network
net = tflearn.input_data(shape=[None, 256, 256, 3])
net = tflearn.conv_2d(net, 16, 3, regularizer='L2', weight_decay=0.0001)
net = tflearn.residual_block(net, n, 16)
net = tflearn.residual_block(net, 1, 32, downsample=True)
net = tflearn.residual_block(net, n - 1, 32)
net = tflearn.residual_block(net, 1, 64, downsample=True)
net = tflearn.residual_block(net, n - 1, 64)
net = tflearn.batch_normalization(net)
net = tflearn.activation(net, 'relu')
net = tflearn.global_avg_pool(net)
# Regression
net = tflearn.fully_connected(net, 2, activation='softmax')
net = tflearn.regression(net, optimizer='adam',
loss='categorical_crossentropy')
return net
def train():
# 读取训练集
(X, Y), (X_test, Y_test) = read_data()
# 向量转成矩阵,为了计算交叉熵
# tflearn.data_utils.to_categorical (y, nb_classes) Convert class vector (integers from 0 to nb_classes) to binary class matrix, for use with categorical_crossentropy.
Y = tflearn.data_utils.to_categorical(Y, 2)
Y_test = tflearn.data_utils.to_categorical(Y_test, 2)
# 定义训练模型,DNN——深度神经网络
model = tflearn.DNN(resnet(), checkpoint_path='model_resnet',
max_checkpoints=10, tensorboard_verbose=0,
clip_gradients=0.)
if os.path.exists(pjoin(MODEL_PATH, MODEL_NAME)):
model.load(pjoin(MODEL_PATH, MODEL_NAME))
# 参数n_epoch表示训练多少轮,嫌太慢可以把它改小
model.fit(X, Y, n_epoch=200, validation_set=(X_test, Y_test),
snapshot_epoch=False, snapshot_step=500,
show_metric=True, batch_size=16, shuffle=True,
run_id='resnet_cat_dog')
# 存储训练结果
model.save(pjoin(MODEL_PATH, MODEL_NAME))
#执行训练
if __name__ == '__main__':
train()
#filename: predict.py
import os
import numpy as np
import tflearn
from image_utils import preprocess_image
from train import resnet
pjoin = os.path.join
MODEL_PATH = pjoin(os.path.dirname(__file__), 'model')
MODEL_NAME = 'resnet_dogs_vs_cats.model'
import tensorflow as tf
tf.app.flags.DEFINE_string('image', None, 'image to classify')
FLAGS = tf.app.flags.FLAGS
#以上内容可以无视
def predict(image_file):
print('file %s' % image_file)
# 加载图片,预处理
image = preprocess_image(image_file, [256, 256, 3])
# 创建DNN模型
model = tflearn.DNN(resnet())
# 加载模型数据
model.load(pjoin(MODEL_PATH, MODEL_NAME))
# 计算
y_pred = model.predict([image])
label = np.argmax(y_pred[0])
return 'Cat' if label == 0 else 'Dog'
if __name__ == '__main__':
# 不知道FLAGS.image这一坨什么意思,实际上填入文件名即可,例如 pred = predict("images\dog.3.jpg")
pred = predict(FLAGS.image)
print('It\'s a picture of %s!' % pred)