AlexNet网络解决花朵分类问题
作者:互联网
代码(Tensorflow2.0):
prepare_data.py
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers, datasets, Sequential, metrics, optimizers
import os
import numpy as np
import cv2
import glob
from dataset import make_anime_dataset
tf.random.set_seed(0)
np.random.seed(0)
os.environ['TF_CPP_MIN_LEVEL'] = '2'
assert tf.__version__.startswith('2.')
# 裁剪图片大小为[227,227]
def cut_picture():
j = 0
img_path = glob.glob(r'.\flower_photos\sunflowers\*.jpg') # 得到所有图片的路径
for i in img_path:
img = cv2.imread(i)
cropped = img[0:227, 0:227]
cv2.imwrite(r'.\flower_cut\sunflowers\sunflowers_%d.jpg'%j, cropped)
print('第{}幅画裁剪完成!'.format(j))
j += 1
# cut_picture()
# 删除掉图片大小不等于[227, 227]的图片
def delete_picture():
flower_name = ['daisy', 'dandelion', 'roses', 'tulips']
for v in flower_name:
print(v)
img_path = glob.glob(r'.\flower_cut\%s\*.jpg'%v) # 得到所有图片的路径
j = 0
for i in img_path:
img = cv2.imread(i)
if img.shape[0] != 227 or img.shape[1] != 227:
os.remove(i)
print('第{}幅画删除完成!'.format(j))
j += 1
# delete_picture()
# 创建数据集(训练集和测试集) 训练集 5*200张图片
def pre_train():
flower_name = ['sunflowers', 'daisy', 'dandelion', 'roses', 'tulips']
for v in flower_name:
print(v)
img_path = glob.glob(r'.\flower_cut\%s\*.jpg' %v) # 得到所有图片的路径
j = 0
for i in img_path:
img = cv2.imread(i)
cv2.imwrite(r'.\flower_cut\train_data\{}_{}.jpg'.format(v, str(j)), img)
os.remove(i)
print('{}花第{}幅画已经转移完成!'.format(v, j))
j += 1
if j == 200:
break
# pre_train()
# 测试集 5*200张图片
def pre_test():
flower_name = ['sunflowers', 'daisy', 'dandelion', 'roses', 'tulips']
for v in flower_name:
print(v)
img_path = glob.glob(r'.\flower_cut\%s\*.jpg' %v) # 得到所有图片的路径
j = 0
for i in img_path:
img = cv2.imread(i)
cv2.imwrite(r'.\flower_cut\test_data\{}_{}.jpg'.format(v, str(j)), img)
os.remove(i)
print('{}花第{}幅画已经转移完成!'.format(v, j))
j += 1
if j == 200:
break
# pre_test()
AlexNet.py
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers, datasets, Sequential, metrics, optimizers
import os
import numpy as np
import cv2
import glob
from dataset import make_anime_dataset
tf.random.set_seed(0)
np.random.seed(0)
os.environ['TF_CPP_MIN_LEVEL'] = '2'
assert tf.__version__.startswith('2.')
# 获取数据集
# img_path = glob.glob(r'.\flower_cut\train_data\*.jpg')
# img, img_shape, img_aa = make_anime_dataset(img_path, batch_size=10)
# sample = next(iter(img))
# img_path = glob.glob(r'.\flower_cut\train_data\*.jpg') # 得到所有图片的路径
# j = 0
# for i in img_path:
# img = cv2.imread(i)
# A = tf.equal(img, sample[j])
# print(A)
# j += 1
# if j == 10:
# break
def get_Xtrain_data():
img_path = glob.glob(r'.\flower_cut\train_data\*.jpg')
j = 0
x = []
for i in img_path:
img = cv2.imread(i)
x.append(img)
x = np.array(x)
return x
def get_Ydata():
y0 = [0] * 200
y1 = [1] * 200
y2 = [2] * 200
y3 = [3] * 200
y4 = [4] * 200
y = np.hstack((y0, y1))
y = np.hstack((y, y2))
y = np.hstack((y, y3))
y = np.hstack((y, y4))
return y
def get_Xtest_data():
img_path = glob.glob(r'.\flower_cut\test_data\*.jpg')
j = 0
x = []
for i in img_path:
img = cv2.imread(i)
x.append(img)
x = np.array(x)
return x
batch_size = 20
epochs = 200
optimizer = optimizers.Adam(lr=0.0001)
def preprocess(x, y):
x = tf.cast(x, dtype=tf.float32)/255.
y = tf.cast(y, dtype=tf.int32)
y = tf.one_hot(y, depth=5)
return x, y
x_train = get_Xtrain_data()
y_train = get_Ydata()
x_test = get_Xtest_data()
y_test = get_Ydata()
print('train_shape:', x_train.shape, y_train.shape, y_train.min(), y_train.max())
train_db = tf.data.Dataset.from_tensor_slices((x_train, y_train))
train_db = train_db.map(preprocess).shuffle(1000).batch(batch_size)
test_db = tf.data.Dataset.from_tensor_slices((x_test, y_test))
test_db = test_db.map(preprocess).batch(batch_size)
class AlexNet(keras.Model):
def __init__(self):
super(AlexNet, self).__init__()
self.conv = Sequential([
# unit1 [b,28,28,1] => [b,14,14,16]
layers.Conv2D(96, (11, 11), padding='valid', strides=4, activation=tf.nn.relu),
layers.MaxPool2D(pool_size=(3, 3), strides=2, padding='same'),
layers.BatchNormalization(), # 使用bn层代替LRN
# unit2 [b,14,14,16] => [b,7,7,32]
layers.Conv2D(256, (5, 5), padding='same', strides=1, activation=tf.nn.relu),
layers.MaxPool2D(pool_size=(3, 3), strides=2, padding='same'),
layers.BatchNormalization(),
# unit3 [b,7,7,32] => [b,7,7,64]
layers.Conv2D(384, (3, 3), padding='same', strides=1, activation=tf.nn.relu),
# unit4 [b,7,7,64] => [b,7,7,128]
layers.Conv2D(384, (3, 3), padding='same', strides=1, activation=tf.nn.relu),
# unit5 [b,7,7,128] => [b,4,4,256]
layers.Conv2D(256, (3, 3), padding='valid', strides=1, activation=tf.nn.relu),
layers.MaxPool2D(pool_size=(3, 3), strides=2, padding='same'),
layers.BatchNormalization(),
])
self.fc = Sequential([
# fc1
layers.Dense(4096, activation=tf.nn.relu),
layers.Dropout(0.4),
# fc2
layers.Dense(2048, activation=tf.nn.relu),
layers.Dropout(0.4),
# fc3
layers.Dense(1024, activation=tf.nn.relu),
layers.Dropout(0.4),
# fc4
layers.Dense(5, activation=tf.nn.relu)
])
def call(self, inputs, training=None):
x = inputs
out = self.conv(x)
out = tf.reshape(out, (-1, 6*6*256))
out = self.fc(out)
return out
model = AlexNet()
# 检查网络输出的shape
# x = tf.random.normal((1, 227, 227, 3))
# out = model(x)
# print(out.shape)
# 输出网络模型的结构
# model.build(input_shape=(None, 227, 227, 3))
# model.summary()
def main():
model.compile(optimizer=optimizers.Adam(lr=0.00001),
loss=tf.losses.CategoricalCrossentropy(from_logits=True),
metrics=['acc'])
model.fit(train_db, epochs=epochs, validation_data=test_db, validation_freq=2)
if __name__ == '__main__':
main()
承接上一篇随笔,这里使用AlexNet网络做了花朵分类的任务。总共分为五类,分别为:
'sunflowers', 'daisy', 'dandelion', 'roses', 'tulips'五类,
训练集和测试集分别1000张,大小为227*227*3,首先下载好数据集,将五类图片进行裁剪,随后将图片封装到俩个文件夹中,
将图片读取到网络中进行训练,其中label是自己标注的。
网络大概训练了27个epoch,在训练集上准确率为90%左右,测试集准确率为60%左右,存在一定的过拟合。再添加L2正则或者
修改损失函数和learning_rata之后正确率应该可以更高。
训练图片:
数据集图片:
标签:layers,flower,花朵,img,分类,train,tf,path,AlexNet 来源: https://www.cnblogs.com/yuganwj/p/13472295.html