[英]CNN Semantic segmentation network (UNET) performing poorly when tested with images
[英]CNN for image classification performing poorly
我正在构建一个用于膝关节 X 射线图像处理的 CNN,但是在每次运行的第 7-8 个 Epoch 之后,验证和训练损失/准确性不对齐,一段时间后验证损失开始增加。 我尝试通过数据增强来增加我的数据集。 现在我想知道是否可能是图像的质量、我的实际架构或我保存数据的方式。 对于我的数据预处理,我将每个图像保存为一个 numpy 数组,然后将其写入一个 pickle 文件。 我也不太确定如何确定层数和超参数,但我确实从其他 cnn 那里得到了指导。 我不知道还有什么可以尝试的。 我将不胜感激有关如何改进此模型的建议。
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
from matplotlib.pyplot import imshow
from sklearn.utils import shuffle
from sklearn.model_selection import train_test_split
import numpy as np
import random as rd
import boto3
import tempfile
import os
import io
import pickle
import tensorflow as tf
import keras
from keras.utils import to_categorical
from keras import optimizers
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import Dropout
from keras.layers import Flatten
from keras.layers import Input, InputLayer
from keras.models import Model
from keras.utils import to_categorical
from keras.layers.convolutional import Conv2D
from keras.layers.convolutional import MaxPooling2D
from keras.layers.pooling import GlobalMaxPooling2D
from keras.models import model_from_json
from keras.layers import MaxPool2D, InputLayer, BatchNormalization
s3_client = boto3.client('s3')
my_array2 = []
labels = []
labels2 = []
x_train = []
x_test = []
y_train = []
y_test = []
def load_data():
# download without using disk
global my_array2
my_array_data2 = io.BytesIO()
s3_client.download_fileobj('msckneeoadata', 'KneeKL224AllReduced.pkl', my_array_data2)
my_array_data2.seek(0)
my_array2 = pickle.load(my_array_data2)
def load_labels():
for x in range(3000):
labels.append(0)
for x in range(3000):
labels.append(1)
for x in range(3000):
labels.append(2)
for x in range(3000):
labels.append(3)
for x in range(3000):
labels.append(4)
def ShuffleData():
global labels
global my_array2
my_array2, labels = shuffle(my_array2, labels, random_state=0)
def SplitData():
# split into 80% for train and 20% for test
global x_train
global x_test
global y_train
global y_test
global my_array2
x_train, x_test, y_train, y_test = train_test_split(my_array2, labels, test_size=0.20, random_state=0)
x_train = np.array(x_train)
y_train = np.array(y_train,dtype='uint8')
x_test = np.array(x_test)
y_test = np.array(y_test,dtype='uint8')
#one-hot encode target column
y_train = to_categorical(y_train)
y_test = to_categorical(y_test)
#train the model
x_train = x_train.reshape(12000,224,224,1)
x_test = x_test.reshape(3000,224,224,1)
x_train = x_train.astype('float64')
x_test = x_test.astype('float64')
x_train/=255
x_test/=255
def create_model():
global x_train
global x_test
global y_train
global y_test
#create model
model = Sequential()
#add model layers
model.add(Conv2D(input_shape=(224,224,1),filters=64,kernel_size=(11,11),padding="same", `activation="relu",name="Conv1_1"))`
model.add(MaxPooling2D(pool_size=(2,2),strides=(2,2), name="Pool1_1"))
model.add(Conv2D(filters=128,kernel_size=(7,7),padding="same", activation="relu",name="Conv2_1"))
model.add(MaxPooling2D(pool_size=(2,2),strides=(2,2), name="Pool2_1"))
model.add(Conv2D(filters=256,kernel_size=(5,5),padding="same", activation="relu",name="Conv3_1"))
model.add(MaxPooling2D(pool_size=(2,2),strides=(2,2), name="Pool3_1"))
model.add(Conv2D(filters=512,kernel_size=(3,3),padding="same", activation="relu",name="Conv4_1"))
model.add(MaxPooling2D(pool_size=(2,2),strides=(2,2), name="Pool4_1"))
model.add(Flatten())
model.add(Dense(units=1024,activation="relu"))
model.add(Dropout(0.1))
model.add(Dense(units=5, activation="softmax",name="fc6"))
#compile model using accuracy to measure model performance
from keras.optimizers import SGD
opt = SGD(lr=0.1)
model.compile(loss = "categorical_crossentropy", optimizer = 'adam',metrics=['accuracy'])
model.fit(x_train, y_train, validation_data=(x_test, y_test), epochs=15,batch_size=150)
# Evaluate the model on the test data using `evaluate`
print('\n# Evaluate on test data')
results = model.evaluate(x_test, y_test, batch_size=100)
print('test loss, test acc:', results)
def main():
load_data()
load_labels()
ShuffleData()
SplitData()
create_model()
我会首先调整你的内核大小,因为它最突出。 这个想法是在网络的顶部创建一些简单的特征,并允许它们随着数据在网络中的涓涓细流而通过过滤器的数量来构建复杂性。
model.add(Conv2D(input_shape=(224,224,1),filters=32,kernel_size=2,padding="same", `activation="relu",name="Conv1_1"))`
model.add(MaxPooling2D(pool_size=2, name="Pool1_1"))
model.add(Conv2D(filters=64,kernel_size=2,padding="same", activation="relu",name="Conv2_1"))
model.add(MaxPooling2D(pool_size=2, name="Pool2_1"))
model.add(Conv2D(filters=128,kernel_size=2,padding="same", activation="relu",name="Conv3_1"))
model.add(MaxPooling2D(pool_size=2, name="Pool3_1"))
您甚至可以删除一个卷积层,然后尝试 3。
其他想法:
此外,我注意到您没有使用为其设置自定义 LR 的优化器,您可以尝试稍微降低 LR,因为您当前使用的是 Adam 的默认设置。
来自 tensorflow 的这个教程提供了一个评估不同架构的好例子:https ://www.tensorflow.org/tutorials/keras/overfit_and_underfit
另一个非常重要的一点是学习率。 在您的代码中,您使用学习率=0.1 的 SGD,但最终您没有使用它。 我建议使用较低的学习率,例如 1e-3。 您也可以尝试以低 epoch 进行训练,如果模型仍在改进,您可以进一步训练。
如果你很难找到一个好的学习率,这是一个很大的帮助: https : //gist.github.com/WittmannF/c55ed82d27248d18799e2be324a79473
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.