Keras-我的模型总是返回精度“ 0”而损失“ nan”

时间:2019-02-07 01:34:17

标签: python tensorflow keras deep-learning conv-neural-network

我有以下Keras代码,试图训练图像和实数特征向量的组合:

from keras.layers import (Conv2D, Flatten, Lambda, Dense, concatenate,
                         Dropout, Input )
from keras.models import Model
import pandas as pd
import numpy as np
import cv2
import os

def label_img(img):
    word_label = img.split('.')[-3]
    if word_label == 'r':
        return 1
    elif word_label == 'i':
        return 0

train_directory = '/train'
images = []
y = []

dataset = pd.read_csv('features.csv')

dataset = dataset[[ 'first_value',
                    'second_value']]

features = dataset.iloc[:,0:2].values

for root, dirs, files in os.walk(train_directory):
    for file in files:
        image = cv2.imread(root + '/' + file)
        image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
        image = cv2.resize(image,(512,512),interpolation=cv2.INTER_AREA)
        images.append(image)
        label = label_img(file)
        y.append(label)

images = np.asarray(images)
images = images.reshape((-1,512,512,1))

image_input = Input(shape=(512,512,1))
aux_input = Input(shape=(2,))

input_layer = Conv2D(32,(5,5), activation='relu')(image_input)
cov1 = Conv2D(24,(5,5), activation='relu', subsample=(2,2))(input_layer)
cov2 = Conv2D(36,(5,5), activation='relu', subsample=(2,2))(cov1)
cov3 = Conv2D(48,(5,5), activation='relu', subsample=(2,2))(cov2)
cov4 = Conv2D(64,(5,5), activation='relu')(cov3)
cov5 = Conv2D(64,(3,3), activation='relu')(cov4)
dropout = Dropout(0.5)(cov5)
flatten = Flatten()(dropout)

# Here we add in the feature vectors 
merge = concatenate([flatten, aux_input])

d1 = Dense(100, activation='elu')(merge)
d2 = Dense(50, activation='elu')(d1)
d3 = Dense(10, activation='elu')(d2)
out = Dense(1)(d3)

model = Model(inputs=[image_input, aux_input], outputs=[out])
model.compile(loss='binary_crossentropy', optimizer='adam',metrics=['acc'])
model.fit([images, features], y, epochs=50)

但是,我得到如下信息:

Epoch 2/50
5/5 [==============================] - 0s - loss: nan - acc: 0.0000e+00
Epoch 3/50
5/5 [==============================] - 0s - loss: nan - acc: 0.0000e+00
Epoch 4/50
5/5 [==============================] - 0s - loss: nan - acc: 0.0000e+00
Epoch 5/50
...
...
...

那是为什么?我该如何解决这个问题?

我要提到的是,我的图像是黑色背景图像,前景显示原始图像的边缘。我不确定这根本不是问题,因为图像中没有太多数据?

谢谢。

1 个答案:

答案 0 :(得分:2)

要正确使用交叉熵,您需要确保网络的输出介于0和1之间。因此,应在最后一层使用Sigmoid或softmax激活。

Elu或线性激活允许使用负值,当使用交叉熵时,这将导致无限损失。另一方面,如果输出值大于以前的值,则可能会发生,并且我们不能确保交叉熵损失保持正值,因此此时最小化不再有意义。

这是由交叉熵的定义引起的:

-(y_true * log(y_pred)+(1-y_true)* log(1-y_pred))

未定义小于零的对数。