CNN 与 Keras - 准确性低得令人难以置信,损失为负 - 显然是我的错误



我正在尝试建立一个CNN,将皮肤癌相关的图像分为七类。 我对CNN的概念相对较新,并且一直在调整狗/猫分类用例以适应已知的皮肤癌数据库挑战。 问题是损耗和精度极低,并且在整个时期都是恒定的。 不过,我不确定问题出在哪里 - 我的第一个假设是使用的图像数量太少:436 个样本用于训练和 109 个验证。我使用的图像数量从 10000+ 减少,因为我使用的是 MacBook Pro。

脚本:

import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Dropout, Activation, Flatten, Conv2D, MaxPooling2D
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import sys
import os
import cv2
DATA_DIR = "/Users/namefolder/PycharmProjects/skin-cancer/HAM10000_images_part_1"
metadata = pd.read_csv(os.path.join(DATA_DIR, 'HAM10000_metadata.csv'))
lesion_type_dict = {'nv': 'Melanocytic nevi',
'mel': 'Melanoma',
'bkl': 'Benign keratosis-like lesions ',
'bcc': 'Basal cell carcinoma',
'akiec': 'Actinic keratoses',
'vasc': 'Vascular lesions',
'df': 'Dermatofibroma'}
metadata['cell_type'] = metadata['dx'].map(lesion_type_dict.get)
metadata['dx_code'] = pd.Categorical(metadata['dx']).codes
# save array of image-id and diagnosis-type (categorical)
metadata = metadata[['image_id', 'dx', 'dx_type', 'dx_code']]
training_data = []
IMG_SIZE=40
# preparing training data
def creating_training_data(path):
for img in os.listdir(path):
try:
img_array = cv2.imread(os.path.join(path, img), cv2.IMREAD_GRAYSCALE)
new_array = cv2.resize(img_array, (IMG_SIZE, IMG_SIZE))
for index, row in metadata.iterrows():
if img == row['image_id']+'.jpg':
try:
training_data.append([new_array, row['dx_code']])
except Exception as ee:
pass
except Exception as e:
pass
return training_data
training_data = creating_training_data(DATA_DIR)
import random
random.shuffle(training_data)
# Splitting data into X features and Y label
X_train = []
y_train = []
for features, label in training_data:
X_train.append(features)
y_train.append(label)
# Reshaping of the data - required by Tensorflow and Keras (*necessary step of deep-learning using these repos)
X_train = np.array(X_train).reshape(-1, IMG_SIZE, IMG_SIZE, 1)
# Normalize data - to reduce processing requirements
X_train = X_train/255.0
# model configuration
model = Sequential()
model.add(Conv2D(64, (3,3), input_shape = X_train.shape[1:]))
model.add(Activation("relu"))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(64, (3,3)))
model.add(Activation("relu"))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Flatten())
model.add(Dense(64))
model.add(Dense(1))
model.add(Activation("softmax"))
model.compile(loss="mean_squared_error",
optimizer="adam",
metrics=["accuracy"])

训练模式:

Model fitting output:
Train on 436 samples, validate on 109 samples
Epoch 1/20
436/436 [==============================] - 1s 2ms/sample - loss: 11.7890 - acc: 0.0688 - val_loss: 13.6697 - val_acc: 0.0642
Epoch 2/20
436/436 [==============================] - 1s 1ms/sample - loss: 11.7890 - acc: 0.0688 - val_loss: 13.6697 - val_acc: 0.0642
Epoch 3/20
436/436 [==============================] - 1s 1ms/sample - loss: 11.7890 - acc: 0.0688 - val_loss: 13.6697 - val_acc: 0.0642
Epoch 4/20
436/436 [==============================] - 1s 1ms/sample - loss: 11.7890 - acc: 0.0688 - val_loss: 13.6697 - val_acc: 0.0642
Epoch 5/20
436/436 [==============================] - 1s 1ms/sample - loss: 11.7890 - acc: 0.0688 - val_loss: 13.6697 - val_acc: 0.0642
Epoch 6/20
436/436 [==============================] - 1s 1ms/sample - loss: 11.7890 - acc: 0.0688 - val_loss: 13.6697 - val_acc: 0.0642
Epoch 7/20
436/436 [==============================] - 1s 1ms/sample - loss: 11.7890 - acc: 0.0688 - val_loss: 13.6697 - val_acc: 0.0642
Epoch 8/20
436/436 [==============================] - 1s 1ms/sample - loss: 11.7890 - acc: 0.0688 - val_loss: 13.6697 - val_acc: 0.0642
Epoch 9/20
436/436 [==============================] - 1s 1ms/sample - loss: 11.7890 - acc: 0.0688 - val_loss: 13.6697 - val_acc: 0.0642
Epoch 10/20
436/436 [==============================] - 1s 1ms/sample - loss: 11.7890 - acc: 0.0688 - val_loss: 13.6697 - val_acc: 0.0642
Epoch 11/20
436/436 [==============================] - 1s 1ms/sample - loss: 11.7890 - acc: 0.0688 - val_loss: 13.6697 - val_acc: 0.0642
Epoch 12/20
436/436 [==============================] - 1s 1ms/sample - loss: 11.7890 - acc: 0.0688 - val_loss: 13.6697 - val_acc: 0.0642
Epoch 13/20
436/436 [==============================] - 1s 1ms/sample - loss: 11.7890 - acc: 0.0688 - val_loss: 13.6697 - val_acc: 0.0642
Epoch 14/20
436/436 [==============================] - 1s 1ms/sample - loss: 11.7890 - acc: 0.0688 - val_loss: 13.6697 - val_acc: 0.0642
Epoch 15/20
436/436 [==============================] - 1s 1ms/sample - loss: 11.7890 - acc: 0.0688 - val_loss: 13.6697 - val_acc: 0.0642
Epoch 16/20
436/436 [==============================] - 1s 1ms/sample - loss: 11.7890 - acc: 0.0688 - val_loss: 13.6697 - val_acc: 0.0642
Epoch 17/20
436/436 [==============================] - 1s 1ms/sample - loss: 11.7890 - acc: 0.0688 - val_loss: 13.6697 - val_acc: 0.0642
Epoch 18/20
436/436 [==============================] - 1s 1ms/sample - loss: 11.7890 - acc: 0.0688 - val_loss: 13.6697 - val_acc: 0.0642
Epoch 19/20
436/436 [==============================] - 1s 1ms/sample - loss: 11.7890 - acc: 0.0688 - val_loss: 13.6697 - val_acc: 0.0642
Epoch 20/20
436/436 [==============================] - 1s 1ms/sample - loss: 11.7890 - acc: 0.0688 - val_loss: 13.6697 - val_acc: 0.0642

模型摘要:

Model: "sequential_16"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv2d_30 (Conv2D)           (None, 38, 38, 64)        640       
_________________________________________________________________
activation_44 (Activation)   (None, 38, 38, 64)        0         
_________________________________________________________________
max_pooling2d_30 (MaxPooling (None, 19, 19, 64)        0         
_________________________________________________________________
conv2d_31 (Conv2D)           (None, 17, 17, 64)        36928     
_________________________________________________________________
activation_45 (Activation)   (None, 17, 17, 64)        0         
_________________________________________________________________
max_pooling2d_31 (MaxPooling (None, 8, 8, 64)          0         
_________________________________________________________________
flatten_14 (Flatten)         (None, 4096)              0         
_________________________________________________________________
dense_28 (Dense)             (None, 64)                262208    
_________________________________________________________________
dense_29 (Dense)             (None, 1)                 65        
_________________________________________________________________
activation_46 (Activation)   (None, 1)                 0         
=================================================================
Total params: 299,841
Trainable params: 299,841
Non-trainable params: 0

有人可以告诉我是否可能是这种情况或确实如此. 您看到我需要更改/修复的其他区域吗?

提前感谢!

您正在使用

model.add(Dense(1))
model.add(Activation("softmax"))

即,只有一个神经元的致密层与softmax?这是行不通的,您至少需要输出的维度为 2 才能使用 softmax。

您的标签是如何表示的?

您好,在这里写我的建议,因为我还没有获得评论权。

首先,你可能完全正确地假设你需要更多的数据。此外,您可能还应考虑数据可能偏斜,以便一个类可以更频繁地出现在数据中。我真的不知道你是如何选择样品的......但是,您可能希望注意小样本中类的实现分布。

至于建议,我不确定你试图预测什么,但我想你想找出图像是否癌变。如果是这种情况,你就会遇到二元分类问题,就像猫和狗一样。因此,您应该在输出层中使用"sigmoid"激活函数,而不是"softmax"。Softmax主要用于多分类。

此外,我没有看到您的代码有任何更深层次的问题。因此,如果可能的话,尝试更改激活函数并使用更多具有正确分布的样本。

希望这对:)有所帮助

最新更新