“损失:0.0000e+00 - acc:1.0000 - val_loss:0.0000e+00 - val_acc:1.0000”是什么意思?

时间:2021-05-20 17:47:39

标签: python transfer-learning vgg-net image-classification

我试图将皮肤病分为 4 类。我尝试使用 VGG16 进行迁移学习。无论我做出什么改变,它都不是分类。准确度为 1,损失为 0。但我认为它也不会过度拟合,因为通过混淆矩阵,我知道它将所有内容都归类为单个类。

import json
import math
import os
import cv2
from PIL import Image
import numpy as np
from keras import layers
from keras.callbacks import Callback, ModelCheckpoint, ReduceLROnPlateau, TensorBoard
from keras.models import Model
from keras.applications.vgg16 import VGG16, preprocess_input
from keras.preprocessing.image import ImageDataGenerator
from keras.utils.np_utils import to_categorical
from keras.models import Sequential
from keras.optimizers import Adam
import matplotlib.pyplot as plt
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.metrics import cohen_kappa_score, accuracy_score
import scipy
import tensorflow as tf
from keras import backend as K
import gc
from functools import partial
from tqdm import tqdm
from sklearn import metrics
from collections import Counter
import json
import itertools
from keras.optimizers import Adam
from keras.applications.vgg16 import VGG16, preprocess_input
from keras.preprocessing.image import ImageDataGenerator
from keras.callbacks import ModelCheckpoint, EarlyStopping
from keras.layers import Dense, Dropout, Flatten

#loading data and data preparation

def Dataset_loader(DIR, RESIZE, sigmaX=10):
    IMG = []
    read = lambda imname: np.asarray(Image.open(imname).convert("RGB"))
    for IMAGE_NAME in tqdm(os.listdir(DIR)):
        PATH = os.path.join(DIR,IMAGE_NAME)
        _, ftype = os.path.splitext(PATH)
        if ftype == ".jpg":
            img = read(PATH)

            img = cv2.resize(img, (RESIZE,RESIZE))

            IMG.append(np.array(img))
    return IMG

eczema_train = np.array(Dataset_loader('/content/medical-image-analysis/train/Eczema Photos', 224))
melanoma_train = np.array(Dataset_loader('/content/medical-image-analysis/train/Melanoma Skin Cancer Nevi and Moles',224))
psoriasis_train = np.array(Dataset_loader('/content/medical-image-analysis/train/Psoriasis pictures Lichen Planus and related diseases',224))

#labelling 
eczema_train_label = np.zeros(len(eczema_train))
melonoma_train_label = np.zeros(len(melanoma_train))
psoriasis_train_label = np.zeros(len(psoriasis_train))

X_train = np.concatenate((eczema_train, melanoma_train, psoriasis_train), axis=0,)
Y_train = np.concatenate((eczema_train_label, melonoma_train_label, psoriasis_train_label), axis=0,)

#train and evaluation split
X_train = (X_train-np.mean(X_train))/np.std(X_train)
X_train, X_test, Y_train, Y_test = train_test_split(
    X_train, Y_train, 
    test_size=0.3, 
    random_state=1
)
X_test, X_val, Y_test, Y_val = train_test_split(
    X_test, Y_test, 
    test_size=0.3, 
    random_state=1
)

s = np.arange(X_train.shape[0])
np.random.shuffle(s)
X_train = X_train[s]
Y_train = Y_train[s]

pre_trained_model = VGG16(input_shape=(224, 224, 3), include_top=False, weights="imagenet")

for layer in pre_trained_model.layers:
    print(layer.name)
    layer.trainable = False
    
print(len(pre_trained_model.layers))

last_layer = pre_trained_model.get_layer('block5_pool')
print('last layer output shape:', last_layer.output_shape)
last_output = last_layer.output

# Flatten the output layer to 1 dimension
x = layers.GlobalMaxPooling2D()(last_output)
# Add a fully connected layer with 512 hidden units and ReLU activation
x = layers.Dense(128, activation='softmax')(x)
# Add a dropout rate of 0.5
x = layers.Dropout(0.5)(x)
# Add a final sigmoid layer for classification
x = layers.Dense(4, activation='softmax')(x)

# Configure and compile the model

model = Model(pre_trained_model.input, x)
optimizer = Adam(lr=0.0001, beta_1=0.9, beta_2=0.9999, epsilon=None, decay=0.0, amsgrad=True)
model.compile(loss='categorical_crossentropy',
              optimizer=optimizer,
              metrics=['accuracy'])

train_datagen = ImageDataGenerator(rotation_range=60,
                    shear_range=0.2,
                    zoom_range=0.2,
                    width_shift_range=0.2,
                    height_shift_range=0.2,
                    horizontal_flip=True,
                    fill_mode='nearest')

train_datagen.fit(X_train)

val_datagen = ImageDataGenerator()
val_datagen.fit(X_val)

batch_size = 64
epochs = 3
history = model.fit(train_datagen.flow(X_train,Y_train, batch_size=batch_size),
                              epochs = epochs, validation_data = val_datagen.flow(X_val, Y_val),
                              verbose = 1, steps_per_epoch=(X_train.shape[0] // batch_size), 
                              validation_steps=(X_val.shape[0] // batch_size))

这是代码,请您帮忙找出我们出错的地方。提前致谢:)

1 个答案:

答案 0 :(得分:0)

<块引用>
#labelling 
eczema_train_label = np.zeros(len(eczema_train))
melonoma_train_label = np.zeros(len(melanoma_train))
psoriasis_train_label = np.zeros(len(psoriasis_train))

所有这些 numpy 数组都用零填充。无论图像代表湿疹、黑色素瘤还是牛皮癣,您都将其真实标签定义为 0,因此您的模型“学习”到无条件输出 0。使至少两个类别的标签非零。

此外,您使用的是 CategoricalCrossentropy,它仅适用于单热标签编码或二进制分类。改用稀疏分类(或稀疏 softmax)交叉熵。 (请注意,代码中可能还有其他问题,但这个问题是一个常见错误,可能会看到)。