一、环境配置
Anaconda:4.10.3 Python:3.6.2 TensorFlow:1.9.0
二、图片准备
在这个小项目中,我们首先需要自己在网上收集四类图片(每类图片30张,一共120张),这些图片的格式最好是统一的JPG格式,对于分辨率来说没有特定的要求,我们的项目在预处理中可以进行分辨率统一化的预处理(也就是把每一张图片变成一样的分辨率64*64)。 不过要根据你自己的目录把图片放在上面,不然代码可是找不到的。我把图片放在了如图这个地方。 每一张图片都需要整理分类到每一个文件夹中,程序才可以正常找到。比如我把土豆放在这个potato文件夹下。
三、效果展示
在测试代码中点击运行: 便会出现要预测的图片(图片显示不清是因为这个图片的像素只有64*64). 接着,把图片关闭,即可显示出预测是potato(土豆)的可能性是0.984120。
四、源代码
(1)preprocessing.py(图片预处理)
import os
import tensorflow as tf
from PIL import Image
orig_picture = 'E:/python-run-env/train-test/train-data/generate-simple/'
gen_picture = 'E:/python-run-env/train-test/Re_train/image_data/inputdata/'
classes = {'cabbage','carrot','nori','potato'}
num_samples = 120
def create_record():
writer = tf.python_io.TFRecordWriter("dishes_train.tfrecords")
for index, name in enumerate(classes):
class_path = orig_picture +"/"+ name+"/"
for img_name in os.listdir(class_path):
img_path = class_path + img_name
img = Image.open(img_path)
img = img.resize((64, 64))
img_raw = img.tobytes()
print (index,img_raw)
example = tf.train.Example(
features=tf.train.Features(feature={
"label": tf.train.Feature(int64_list=tf.train.Int64List(value=[index])),
'img_raw': tf.train.Feature(bytes_list=tf.train.BytesList(value=[img_raw]))
}))
writer.write(example.SerializeToString())
writer.close()
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)
})
label = features['label']
img = features['img_raw']
img = tf.decode_raw(img, tf.uint8)
img = tf.reshape(img, [64, 64, 3])
label = tf.cast(label, tf.int32)
return img, label
if __name__ == '__main__':
create_record()
batch = read_and_decode('dishes_train.tfrecords')
init_op = tf.group(tf.global_variables_initializer(), tf.local_variables_initializer())
with tf.Session() as sess:
sess.run(init_op)
coord=tf.train.Coordinator()
threads= tf.train.start_queue_runners(coord=coord)
for i in range(num_samples):
example, lab = sess.run(batch)
img=Image.fromarray(example, 'RGB')
img.save(gen_picture+'/'+str(i)+'samples'+str(lab)+'.jpg')
print(example, lab)
coord.request_stop()
coord.join(threads)
sess.close()
点击运行后,可以在终端看到很多输出 然后在这里可以看到很多图片,要把这些图片进行分类,然后装到这些文件夹里面: 除此之外,还会产生一个TFrecord的二进制文件: (2)batchdealing.py(输入图片处理)
import os
import math
import numpy as np
import tensorflow as tf
import matplotlib.pyplot as plt
train_dir = 'E:/python-run-env/train-test/Re_train/image_data/inputdata/'
cabbage = []
label_cabbage = []
carrot = []
label_carrot = []
nori = []
label_nori = []
potato = []
label_potato = []
def get_files(file_dir, ratio):
for file in os.listdir(file_dir+'/cabbage'):
cabbage.append(file_dir +'/cabbage'+'/'+ file)
label_cabbage.append(0)
for file in os.listdir(file_dir+'/carrot'):
carrot.append(file_dir +'/carrot'+'/'+file)
label_carrot.append(1)
for file in os.listdir(file_dir+'/nori'):
nori.append(file_dir +'/nori'+'/'+ file)
label_nori.append(2)
for file in os.listdir(file_dir+'/potato'):
potato.append(file_dir +'/potato'+'/'+file)
label_potato.append(3)
image_list = np.hstack((cabbage, carrot, nori, potato))
label_list = np.hstack((label_cabbage, label_carrot, label_nori, label_potato))
temp = np.array([image_list, label_list])
temp = temp.transpose()
np.random.shuffle(temp)
all_image_list = list(temp[:, 0])
all_label_list = list(temp[:, 1])
n_sample = len(all_label_list)
n_val = int(math.ceil(n_sample*ratio))
n_train = n_sample - n_val
tra_images = all_image_list[0:n_train]
tra_labels = all_label_list[0:n_train]
tra_labels = [int(float(i)) for i in tra_labels]
val_images = all_image_list[n_train:-1]
val_labels = all_label_list[n_train:-1]
val_labels = [int(float(i)) for i in val_labels]
return tra_images, tra_labels, val_images, val_labels
def get_batch(image, label, image_W, image_H, batch_size, capacity):
image = tf.cast(image, tf.string)
label = tf.cast(label, 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, image_W, image_H)
image = tf.image.per_image_standardization(image)
image_batch, label_batch = tf.train.batch([image, label],
batch_size= batch_size,
num_threads= 32,
capacity = capacity)
label_batch = tf.reshape(label_batch, [batch_size])
image_batch = tf.cast(image_batch, tf.float32)
return image_batch, label_batch
(3)forward.py
import tensorflow as tf
def inference(images, batch_size, n_classes):
with tf.variable_scope('conv1') as scope:
weights = tf.Variable(tf.truncated_normal(shape=[3,3,3,64], stddev = 1.0, dtype = tf.float32),
name = 'weights', dtype = tf.float32)
biases = tf.Variable(tf.constant(value = 0.1, dtype = tf.float32, shape = [64]),
name = 'biases', dtype = tf.float32)
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.Variable(tf.truncated_normal(shape=[3,3,64,16], stddev = 0.1, dtype = tf.float32),
name = 'weights', dtype = tf.float32)
biases = tf.Variable(tf.constant(value = 0.1, dtype = tf.float32, shape = [16]),
name = 'biases', dtype = tf.float32)
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')
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.Variable(tf.truncated_normal(shape=[dim,128], stddev = 0.005, dtype = tf.float32),
name = 'weights', dtype = tf.float32)
biases = tf.Variable(tf.constant(value = 0.1, dtype = tf.float32, shape = [128]),
name = 'biases', dtype=tf.float32)
local3 = tf.nn.relu(tf.matmul(reshape, weights) + biases, name=scope.name)
with tf.variable_scope('local4') as scope:
weights = tf.Variable(tf.truncated_normal(shape=[128,128], stddev = 0.005, dtype = tf.float32),
name = 'weights',dtype = tf.float32)
biases = tf.Variable(tf.constant(value = 0.1, dtype = tf.float32, shape = [128]),
name = 'biases', dtype = tf.float32)
local4 = tf.nn.relu(tf.matmul(local3, weights) + biases, name='local4')
with tf.variable_scope('softmax_linear') as scope:
weights = tf.Variable(tf.truncated_normal(shape=[128, n_classes], stddev = 0.005, dtype = tf.float32),
name = 'softmax_linear', dtype = tf.float32)
biases = tf.Variable(tf.constant(value = 0.1, dtype = tf.float32, shape = [n_classes]),
name = 'biases', dtype = tf.float32)
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
(4)backward.py(训练模型)
import os
import numpy as np
import tensorflow as tf
import batchdealing
import forward
N_CLASSES = 4
IMG_W = 64
IMG_H = 64
BATCH_SIZE =20
CAPACITY = 200
MAX_STEP = 200
learning_rate = 0.0001
train_dir = 'E:/python-run-env/train-test/Re_train/image_data/inputdata/'
logs_train_dir = 'E:/python-run-env/train-test/Re_train/image_data/inputdata/'
train, train_label, val, val_label = batchdealing.get_files(train_dir, 0.3)
train_batch,train_label_batch = batchdealing.get_batch(train, train_label, IMG_W, IMG_H, BATCH_SIZE, CAPACITY)
val_batch, val_label_batch = batchdealing.get_batch(val, val_label, IMG_W, IMG_H, BATCH_SIZE, CAPACITY)
train_logits = forward.inference(train_batch, BATCH_SIZE, N_CLASSES)
train_loss = forward.losses(train_logits, train_label_batch)
train_op = forward.trainning(train_loss, learning_rate)
train_acc = forward.evaluation(train_logits, train_label_batch)
test_logits = forward.inference(val_batch, BATCH_SIZE, N_CLASSES)
test_loss = forward.losses(test_logits, val_label_batch)
test_acc = forward.evaluation(test_logits, val_label_batch)
summary_op = tf.summary.merge_all()
sess = tf.Session()
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 % 10 == 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 + 1) == MAX_STEP:
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()
训练结束后,在终端显示: (5)test.py
from PIL import Image
import numpy as np
import tensorflow as tf
import matplotlib.pyplot as plt
import forward
from batchdealing import get_files
def get_one_image(train):
n = len(train)
ind = np.random.randint(0, n)
img_dir = train[ind]
img = Image.open(img_dir)
plt.imshow(img)
plt.show(img)
imag = img.resize([64, 64])
image = np.array(imag)
return image
def evaluate_one_image(image_array):
with tf.Graph().as_default():
BATCH_SIZE = 1
N_CLASSES = 4
image = tf.cast(image_array, tf.float32)
image = tf.image.per_image_standardization(image)
image = tf.reshape(image, [1, 64, 64, 3])
logit = forward.inference(image, BATCH_SIZE, N_CLASSES)
logit = tf.nn.softmax(logit)
x = tf.placeholder(tf.float32, shape=[64, 64, 3])
logs_train_dir = 'E:/python-run-env/train-test/Re_train/image_data/inputdata/'
saver = tf.train.Saver()
with tf.Session() as sess:
print("Reading checkpoints...")
ckpt = tf.train.get_checkpoint_state(logs_train_dir)
if ckpt and ckpt.model_checkpoint_path:
global_step = ckpt.model_checkpoint_path.split('/')[-1].split('-')[-1]
saver.restore(sess, ckpt.model_checkpoint_path)
print('Loading success, global_step is %s' % global_step)
else:
print('No checkpoint file found')
prediction = sess.run(logit, feed_dict={x: image_array})
max_index = np.argmax(prediction)
if max_index==0:
print('This is a cabbage with possibility %.6f' %prediction[:, 0])
elif max_index==1:
print('This is a carrot with possibility %.6f' %prediction[:, 1])
elif max_index==2:
print('This is a nori with possibility %.6f' %prediction[:, 2])
else:
print('This is a potato with possibility %.6f' %prediction[:, 3])
if __name__ == '__main__':
train_dir = 'E:/python-run-env/train-test/Re_train/image_data/inputdata/'
train, train_label, val, val_label = get_files(train_dir, 0.3)
img = get_one_image(val)
evaluate_one_image(img)
点击测试之后,就可以显示如三效果展示那样的效果了,每一次都是随机选取我们自己的图片来测试的。
|