【问题标题】:Neural network only predicts one class神经网络只预测一类
【发布时间】:2021-06-03 19:26:06
【问题描述】:

我的模型只从二元类中预测一个类。该模型使用 Keras Video Frame Generator 获取视频输入,并为每个视频获取 350 帧。该模型必须采用 350 帧的输入序列并使用 BLSTM 输出二进制类。输入形状为 (350, 112, 75, 3)。由于 OOM 错误,批量大小为 2。我不知道这可能是问题还是代码有问题,但模型似乎什么也没学到。这是代码:

from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Conv2D, BatchNormalization, MaxPool2D, GlobalMaxPool2D
def build_convnet(shape=(112, 75, 2)):
    momentum = .9
    model = Sequential()
    model.add(Conv2D(64, (3,3), input_shape=shape, padding='same', activation='relu'))
    model.add(Conv2D(64, (3,3), padding='same', activation='relu'))
    model.add(BatchNormalization(momentum=momentum))
    
    model.add(MaxPool2D())
    
    model.add(Conv2D(128, (3,3), padding='same', activation='relu'))
    model.add(Conv2D(128, (3,3), padding='same', activation='relu'))
    model.add(BatchNormalization(momentum=momentum))
    
    model.add(MaxPool2D())
    
    model.add(Conv2D(256, (3,3), padding='same', activation='relu'))
    model.add(Conv2D(256, (3,3), padding='same', activation='relu'))
    model.add(BatchNormalization(momentum=momentum))
    
    model.add(MaxPool2D())
    
    model.add(Conv2D(512, (3,3), padding='same', activation='relu'))
    model.add(Conv2D(512, (3,3), padding='same', activation='relu'))
    model.add(BatchNormalization(momentum=momentum))
    
    # flatten...
    model.add(GlobalMaxPool2D())
    
    return model
from tensorflow.keras.layers import LSTM, Bidirectional
from tensorflow.keras.layers import TimeDistributed, Dense, Dropout
def action_model(shape=(350, 112, 75, 3), nbout=2):
    # Create our convnet with (112, 75, 3) input shape
    convnet = build_convnet(shape[1:])
    
    # then create our final model
    model = Sequential()
    
    # add the convnet with (350, 112, 75, 3) shape
    model.add(TimeDistributed(convnet, input_shape=shape))
    model.add(Bidirectional(LSTM(units = 512, return_sequences = True, input_shape = (NBFRAME, 112*75*3))))
    model.add(Dropout(0.5))

    # Adding a second LSTM layer and Dropout layer
    model.add(Bidirectional(LSTM(units = 512, return_sequences = True)))
    model.add(Dropout(0.5))

    # Adding a third LSTM layer and Dropout layer
    model.add(Bidirectional(LSTM(units = 512)))
    model.add(Dropout(0.5))
    model.add(Dense(nbout, activation='softmax'))
    model.summary()
    return model

这是模型摘要。

【问题讨论】:

  • 您是否基于视频(不是基于帧)对数据进行了混洗? (假设 350 帧的每个视频都映射到两个类别之一)。不洗牌,训练就会有偏差。
  • 我检查并打印生成器中的视频索引是随机顺序
  • 好的,你会检查学习曲线吗?它是否很早就饱和了(并且损失完全停止减少)?如果是,那么您的模型可能面临Dying ReLU 问题。尝试采用较小的学习率和/或使用一些专门的权重初始化技术,例如He initializationtensorflow.org/api_docs/python/tf/keras/initializers/HeUniform。您也可以尝试ReLU 的其他变体,例如Leakly ReLU
  • 我尝试使用较小的学习率和 Leakly ReLU:在训练过程中,该模型在训练集和验证集上似乎都更好(70-80% 的准确度),但在测试集上的准确度为 52%。跨度>
  • 很高兴知道您的问题已解决。但是您现在面临的问题与问题的问题不同。你最好用代码提出一个新问题,最重要的是用你生成的所有图。但是现在我建议你验证一个事实——训练数据(至少是验证数据)是否能很好地代表测试数据。为了验证它,你可以问自己一个小问题——如果有人将测试数据与训练数据混在一起,你能把它们分开吗?如果可以,那么您的训练数据不好。但如果你不能,那么你的训练数据就可以了。

标签: machine-learning neural-network conv-neural-network tf.keras image-classification


【解决方案1】:

我认为您将大量数据放入内存中,您是否尝试过减少视频的帧数?这有帮助吗?

【讨论】:

  • 数量已经减少了,再多一点,我可能会丢失很多信息
【解决方案2】:

你的模型太大了,我把这块去掉:

emodel.add(Conv2D(128, (3,3), padding='same', activation='relu'))
model.add(Conv2D(128, (3,3), padding='same', activation='relu')) 
model.add(BatchNormalization(momentum=momentum)) 
model.add(MaxPool2D())         
model.add(Conv2D(256, (3,3), padding='same', activation='relu')) 
model.add(Conv2D(256, (3,3), padding='same', activation='relu'))   
model.add(BatchNormalization(momentum=momentum))          
model.add(MaxPool2D())       
model.add(Conv2D(512, (3,3), padding='same', activation='relu'))  
model.add(Conv2D(512, (3,3), padding='same', activation='relu')) 
model.add(BatchNormalization(momentum=momentum))

也许它会导致 oom,也许你不需要它。

【讨论】:

    猜你喜欢
    • 2019-08-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-02
    • 2021-03-31
    • 1970-01-01
    • 1970-01-01
    • 2017-05-20
    • 2012-05-06
    相关资源
    最近更新 更多