今天编写了一段CNN的代码在这里插入代码片
def cnnTrain(self, x_train, y_train, chnel):
model = keras.models.Sequential()
# 第一层卷积
model.add(keras.layers.Conv2D(
filters = 32,
kernel_size = 3,
padding = 'same',
activation = 'selu',
input_shape = (32, 32, 1)
))
# 第二层卷积
model.add(keras.layers.Conv2D(
filters = 32,
kernel_size = 3,
padding = 'same',
activation = 'selu'
))
# 池化层(最大池化)
model.add(keras.layers.MaxPool2D(
pool_size = 2
))
# 第三层卷积
model.add(keras.layers.Conv2D(
filters = 64,
kernel_size = 3,
padding = 'same',
activation = 'selu'
))
# 第四层卷积
model.add(keras.layers.Conv2D(
filters = 64,
kernel_size = 3,
padding = 'same',
activation = 'selu'
))
# 池化层(最大池化)
model.add(keras.layers.MaxPool2D(
pool_size = 2
))
# 第五层卷积
model.add(keras.layers.Conv2D(
filters = 128,
kernel_size = 3,
padding = 'same',
activation = 'selu'
))
# 第六层卷积层
model.add(keras.layers.Conv2D(
filters = 128,
kernel_size = 3,
padding = 'same',
activation = 'selu'
))
# 池化层(最大池化)
model.add(keras.layers.MaxPool2D(
pool_size = 2
))
# flatten层
model.add(keras.layers.Flatten())
# 全连接层
model.add(keras.layers.Dense(128, activation = 'selu'))
# softmax层(输出层)
model.add(keras.layers.Dense(6, activation = 'softmax'))
# 配置模型训练方法
model.compile(
loss = 'sparse_categorical_crossentropy',
# optimizer = 'adam',
optimizer = tf.keras.optimizers.Adam(learning_rate = 0.001),
metrics = ['accuracy']
)
# # 查看模型结构
# model.summary()
# 模型保存路径
logdir = r'.\callbacks_cnn'
# 文件夹是否存在
if not os.path.exists(logdir):
# # 若文件夹已存在先强制删除
# shutil.rmtree(logdir)
# 创建文件夹
os.mkdir(logdir)
# 模型保存路径
global output_model_file
output_model_file = os.path.join(logdir, 'feature_extract_model_'+ chnel +'.h5')
# 创建callbacks数组
callbacks = [
keras.callbacks.TensorBoard(logdir),
keras.callbacks.ModelCheckpoint(output_model_file, save_best_only = True), # 'save_best_only 表示只保存最优模型'
keras.callbacks.EarlyStopping(patience = 5, min_delta = 1e-3)
]
# 模型训练
history = model.fit(
x_train,
y_train,
batch_size = 32,
epochs = 30,
validation_split = 0.2,
# validation_data = (x_valid, y_valid) # validation_split 和 validation_data只能使用一个
callbacks = callbacks
)
return history
数据标签是这样的:
将标签进行onehot编码:
y_train_oneHot = tf.keras.utils.to_categorical(y_train)
得到编码后的标签:
但是运行之后,代码报错:
ValueError: labels.shape
must equal logits.shape
except for the last dimension. Received: labels.shape=(192,) and logits.shape=(32, 6).
经过多次修改后后发现是代码中损失函数的问题:
当 **loss = ‘sparse_categorical_crossentropy’**时,数据的标签不能进行onehot编码,才能运行;
当数据标签进行了onehot编码后,改为 **loss = ‘categorical_crossentropy’**就能跑通了。