import tensorflow as tf
import numpy as np
import os
from model import GoogLeNet
from random import shuffle
import cv2 as cv
from tensorflow.keras import datasets, layers, optimizers, Sequential, metrics, losses
name_dict = {"BF":0,"BK":1,"BL":2,"BR":3,"CF":4,"CL":5,"CV":6,"CXK":7,"S":8,"XF":9}
data_root_path = "color_part_data_processing/"
test_file_path = "TXT_doc/test.txt" #测试集数据集文件
trainer_file_path = "TXT_doc/trainer.txt" #训练集数据集文件
name_data_list = {} #记录每类图片有多少训练图片、测试图片
trainer_list = []
test_list = []
def generateds(train_list):
x, y_ = [], [] # x图片数据,y_为标签
with open(train_list,'r') as f:
#读取所有行
lines = [line.strip()for line in f] #对数据进行掐头去尾放入列表
for line in lines:
img_path, lab = line.strip().split("\t")
img = cv.imread(img_path) #读入图片
img = cv.resize(img,(224,224)) ####对图片进行放缩**********************************
# img = np.array(img.convert('L')) #将图片变为8位宽灰度值的np.array格式
img = img / 255 #数据归一化(实现预处理)
x.append(img) #归一化后的数据,贴到列表x
y_.append(lab)
x = np.array(x)
y_ = np.array(y_)
y_ = y_.astype(np.int64)
return x, y_
x_train , y_train = generateds(trainer_file_path)
x_test, y_test = generateds(test_file_path)
x_train = tf.convert_to_tensor(x_train,dtype=tf.float32)
y_train = tf.convert_to_tensor(y_train,dtype=tf.int32)
x_test = tf.convert_to_tensor(x_test,dtype=tf.float32)
y_test = tf.convert_to_tensor(y_test,dtype=tf.int32)
train_dataset = tf.data.Dataset.from_tensor_slices((x_train,y_train)) #构建数据集对象
train_dataset = train_dataset.batch(32) #设置批量训练的batch为32,要将训练集重复训练10遍
test_dataset = tf.data.Dataset.from_tensor_slices((x_test,y_test))
test_dataset = test_dataset.batch(32)
print("---------------------------------------------网络数据集搭建完成------------------------------------")
# model = tf.keras.models.Sequential([
# tf.keras.layers.Flatten(),
# tf.keras.layers.Dense(128,activation='relu'),
# tf.keras.layers.Dense(10,activation='softmax')
# ])
print('---------------------------------------------模型搭建--------------------------------------------')
network = Sequential([
# 第一层
layers.Conv2D(64, kernel_size=3, strides=1, padding='same', activation='relu'),
layers.MaxPooling2D(pool_size=2, strides=2),
# 第二层
layers.Conv2D(128, kernel_size=3, strides=1, padding='same', activation='relu'),
layers.MaxPooling2D(pool_size=2, strides=2),
# 第三层
layers.Conv2D(256, kernel_size=3, strides=1, padding='same', activation='relu'),
# 第四层
layers.Conv2D(256, kernel_size=3, strides=1, padding='same', activation='relu'),
layers.MaxPooling2D(pool_size=2, strides=2),
# 第五层
layers.Conv2D(512, kernel_size=3, strides=1, padding='same', activation='relu'),
# 第六层
layers.Conv2D(512, kernel_size=3, strides=1, padding='same', activation='relu'),
layers.MaxPooling2D(pool_size=2, strides=2),
# 第七层
layers.Conv2D(512, kernel_size=3, strides=1, padding='same', activation='relu'),
# 第八层
layers.Conv2D(512, kernel_size=3, strides=1, padding='same', activation='relu'),
layers.MaxPooling2D(pool_size=2, strides=2),
layers.Flatten(), # 拉直 7*7*512
# 第九层
layers.Dense(1024, activation='relu'),
layers.Dropout(rate=0.5),
# 第十层
layers.Dense(128, activation='relu'),
layers.Dropout(rate=0.5),
# 第十一层
layers.Dense(10, activation='softmax')
])
network.build(input_shape=(32, 224, 224, 3)) # 设置输入格式
network.summary() # 打印各层参数表
print('---------------------------------------------建立优化器-------------------------------------------')
loss_object = tf.keras.losses.CategoricalCrossentropy(from_logits=False) # 定义损失函数(这种方式需要one-hot编码)
optimizer = optimizers.SGD(lr=0.01) # 声明采用批量随机梯度下降方法,学习率=0.01
acc_meter = metrics.Accuracy() # 新建accuracy测量器
train_loss = tf.keras.metrics.Mean(name='train_loss')
train_accuracy = tf.keras.metrics.CategoricalAccuracy(name='train_accuracy') # 定义平均准确率
test_loss = tf.keras.metrics.Mean(name='test_loss')
test_accuracy = tf.keras.metrics.CategoricalAccuracy(name='test_accuracy')
@tf.function
def train_step(images, labels):
with tf.GradientTape() as tape:
output = network(images, training=True)
labels = tf.one_hot(labels,depth=10) #one-hot编码
loss = loss_object(labels,output)
gradients = tape.gradient(loss, network.trainable_variables)
optimizer.apply_gradients(zip(gradients, network.trainable_variables))
train_loss(loss)
train_accuracy(labels, output)
@tf.function
def test_step(images, labels):
output = network(images, training=False)
labels = tf.one_hot(labels, depth=10) # one-hot编码
t_loss = loss_object(labels, output)
test_loss(t_loss)
test_accuracy(labels, output)
print('------------------------------------------------------------------------------------------------')
best_test_loss = float('inf')
best_test_accuracy = float(0)
epochs= 1000
for epoch in range(1, epochs+1):
train_loss.reset_states() # 训练损失值清零
train_accuracy.reset_states() # clear history info
test_loss.reset_states() # clear history info
test_accuracy.reset_states() # clear history info
for step,(images,labels) in enumerate(train_dataset):
train_step(images,labels)
for step,(imags_val,labels_val) in enumerate(test_dataset):
test_step(imags_val,labels_val)
template = 'Epoch {}, Loss: {}, Accuracy: {}, Test Loss: {}, Test Accuracy: {}'
print(template.format(epoch,
train_loss.result(),
train_accuracy.result() * 100,
test_loss.result(),
test_accuracy.result() * 100))
if test_loss.result() < best_test_loss:
best_test_loss = test_loss.result()
print('best_test_loss:',best_test_loss)
if test_accuracy.result() > best_test_accuracy:
best_test_accuracy = test_accuracy.result()
print('best_test_accuracy:',best_test_accuracy*100)
print('******************************best_test_accuracy*****************************', best_test_accuracy*100)
print('******************************best_test_accuracy*****************************', best_test_accuracy * 100)
# model.save_weights("./save_weights/myGoogLeNet.h5") # 保存模型为.h5格式
训练测试集准确率在70%左右,最好的一次是79.347824%
版权声明:本文为baseclanguage原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。