【问题标题】:Same output of the Keras modelKeras 模型的相同输出
【发布时间】:2019-03-22 07:33:19
【问题描述】:

我有一个用于预测游戏中动作的 Keras 模型。我的输入形状为(160,120 ,1)。我有以下模型,输出为 9 个节点:

from keras.models import Sequential
from keras.layers.core import Dense, Dropout, Activation, Flatten
from keras.layers.convolutional import Conv2D, MaxPooling2D, ZeroPadding2D
from keras.layers.normalization import BatchNormalization
from keras.optimizers import Adam
from keras.regularizers import l2
from keras import optimizers
def alexnet_model(n_classes=9, l2_reg=0.,
    weights=None):

    # Initialize model
    alexnet = Sequential()
    alexnet.add(Conv2D(24, (11, 11), input_shape=(160,120,1), activation ='relu'))
    alexnet.add(MaxPooling2D(pool_size=(2, 2)))
    alexnet.add(BatchNormalization())
    alexnet.add(Conv2D(36, (5, 5), activation ='relu'))
    alexnet.add(MaxPooling2D(pool_size=(2, 2)))
    alexnet.add(Conv2D(48, (3, 3),  activation ='relu'))
    alexnet.add(Conv2D(54, (3, 3),  activation ='relu'))
    alexnet.add(MaxPooling2D(pool_size=(2, 2)))
    alexnet.add(Flatten())
    alexnet.add(Dense(300,   activation ='tanh'))
    alexnet.add(Dropout(0.5))
    alexnet.add(Dense(200,   activation ='tanh'))
    alexnet.add(Dropout(0.5))
    alexnet.add(Dense(100,   activation ='tanh'))
    alexnet.add(Dropout(0.5))


    alexnet.add(Dense(n_classes , activation = 'softmax'))

    optimizer = Adam(lr=1e-3)

    alexnet.compile(loss='categorical_crossentropy', optimizer=optimizer)


    alexnet.summary()


    return alexnet

然后,我运行一个训练脚本。我的X 的形状为(12862, 160, 120, 1)y(1000,9)

import numpy as np
import tensorflow as tf
from random import shuffle
import pandas as pd
from tensorflow.keras import layers,models
from keras.preprocessing.image import ImageDataGenerator
import tensorflow as tf
# what to start at
START_NUMBER = 60

# what to end at
hm_data = 111

# use a previous model to begin?
START_FRESH = False
WIDTH = 160
HEIGHT = 120
LR = 1e-3
EPOCHS = 1

MODEL_NAME = 'model_new.h5'
EXISTING_MODEL_NAME = ''

model = alexnet_model()

X=[]

Y=[]
for i in range(EPOCHS):
    train_data = np.load('training_data_1.npy')
    print(len(train_data))
    train = train_data[0:12862]
    test = train_data[-1000:]

    X = np.array([i[0] for i in train]).reshape(-1,WIDTH,HEIGHT,1)
    Y = np.array([i[1] for i in train])

    test_x = np.array([i[0] for i in test]).reshape(-1,WIDTH,HEIGHT,1)
    test_y = np.array([i[1] for i in test])
    print(X.shape)
    model.fit(X, Y , batch_size = 16, epochs = 10 , validation_data = (test_x, test_y), verbose=1)
    model.save(MODEL_NAME)

# tensorboard --logdir=foo:C:/Users/H/Desktop/ai-gaming-phase5/log

测试模型后,我得到一个输出:

array([[2.8518048e-01, 5.5075828e-03, 7.3730588e-02, 5.3255934e-02,
        1.0635615e-01, 6.4690344e-02, 9.1519929e-08, 7.0413840e-08,
        4.1127869e-01]], dtype=float32)

用这行代码:

model.predict(X[100].reshape(-1,160,120,1)) 

我知道在X 上测试模型不好,但我使用哪张图片并不重要,但我得到相同的输出。仅供参考(我的Y 值):

w = [1,0,0,0,0,0,0,0,0]
s = [0,1,0,0,0,0,0,0,0]
a = [0,0,1,0,0,0,0,0,0]
d = [0,0,0,1,0,0,0,0,0]
wa = [0,0,0,0,1,0,0,0,0]
wd = [0,0,0,0,0,1,0,0,0]
sa = [0,0,0,0,0,0,1,0,0]
sd = [0,0,0,0,0,0,0,1,0]
nk = [0,0,0,0,0,0,0,0,1]

我尝试了另一个模型,但它仍然无法正常工作。以下是每个类的训练数据量:

Counter({'[1, 0, 0, 0, 0, 0, 0, 0, 0]': 5000,
         '[0, 0, 0, 0, 0, 0, 0, 0, 1]': 5000,
         '[0, 0, 0, 0, 1, 0, 0, 0, 0]': 1183,
         '[0, 0, 0, 0, 0, 1, 0, 0, 0]': 982,
         '[0, 0, 1, 0, 0, 0, 0, 0, 0]': 832,
         '[0, 0, 0, 1, 0, 0, 0, 0, 0]': 764,
         '[0, 1, 0, 0, 0, 0, 0, 0, 0]': 101})

我认为问题出在模型上,但我不知道如何更改它。会不会是小训练数据的问题?损失值也没有下降:loss: 1.7416 - val_loss: 1.4639。它只会减少几位小数,有时甚至会回升。

【问题讨论】:

  • "y of (1000, 160,120,1)"??您正在执行 9 类分类。所以y的形状一定是(n_samples, 9)?!!此外,告诉我们更多关于训练结果的信息:训练过程中损失值是否降低?准确性如何?
  • 另外,您能否在 epoch 循环之外加载您的训练数据,将其处理为 X、Y、test_x、test_y 并打印它们中的每一个的形状?使用epochs=10 作为model.fit 的参数来训练多个时期,而不是多次调用model.fit
  • 通常调试这些问题并不容易,特别是通过 Stack Overflow。如果损失没有减少,那就是你的问题,你不应该测试一个没有收敛的模型。此处缺少此类信息。
  • 我刚刚更新了问题
  • @KyrKalash 输入的数据是图片吧?

标签: python machine-learning neural-network keras classification


【解决方案1】:

从它在您的代码中出现的内容来看,并且由于您提到损失正在非常缓慢地减少,因此最好的猜测是输入数据(我认为是图像)没有标准化,因此这会阻止平滑的梯度流。尝试将它们标准化。一种简单的方法是这样的:

X = X.astype('float32') / 255.0
test_x = test_x.astype('float32') / 255.0

此外,您可能需要考虑训练数据中的类不平衡,并通过在 fit 方法中使用 class_weights 参数来解决它(查看文档以了解如何使用它)。

【讨论】:

  • 除以 255 的效果不如 class_weights
【解决方案2】:

解决了! 仅仅标准化训练数据是行不通的。我减少了节点和层的数量,一切正常。我想这是一个过度拟合的问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-03-15
    • 2020-11-15
    • 1970-01-01
    • 2018-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多