【问题标题】:Error in shape (dimention) and type of Keras model inputKeras 模型输入的形状(尺寸)和类型错误
【发布时间】:2021-02-01 08:20:51
【问题描述】:

我迫切希望设置这个简单 Keras 模型的输入形状 :( X 和 Y 都是 numpy.narray 但我不知道它有什么问题!我尝试了不同的 X 形状,但错误就在那里!代码中提供了数据集的信息(尺寸、样本数量等)。 X_train 的 .pkl 文件来自预训练模型的隐藏状态。

import pandas as pd
from sklearn.preprocessing import LabelEncoder
from keras.utils import np_utils
from keras import Input, Model
from keras.layers import Dense
import numpy as np

############################## X_Train ############################

X_Train_3embed1 = pd.read_pickle("XX_Train_3embeding.pkl")


X_Train_3embed = np.array(X_Train_3embed1)

print("X-Train")
print(X_Train_3embed.shape)   # (230, 1, 128)
print(type(X_Train_3embed))  # <class 'numpy.ndarray'>
print(X_Train_3embed[0].shape) # (1, 128)
print(type(X_Train_3embed[0])) # <class 'numpy.ndarray'>


############################## Y_Train ############################

Y_Train_labels_list = pd.read_pickle("lis_Y_all_Train.pkl")

print(type(Y_Train_labels_list))  #<class 'numpy.ndarray'>
print(type(Y_Train_labels_list[0])) #<class 'str'>

encoder = LabelEncoder()
encoder.fit(Y_Train_labels_list)
encoded_Y = encoder.transform(Y_Train_labels_list)
Y_my_Train = np_utils.to_categorical(encoded_Y)


print("Y-Train")
print(Y_my_Train.shape) #(230, 83)
print(type(Y_my_Train)) # <class 'numpy.ndarray'>
print(Y_my_Train[0].shape) # (83,)
print(type(Y_my_Train[0])) # <class 'numpy.ndarray'>

##################################  Model  ##################################

first_input = Input(shape=(1, 128))

first_dense = Dense(128)(first_input)

output_layer = Dense(83, activation='softmax')(first_dense)

model = Model(inputs=first_input, outputs=output_layer)

model.summary()


model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['acc'])


history = model.fit((X_Train_3embed, Y_my_Train), epochs=2, batch_size=32)

结果如下:

Model: "model_1"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_1 (InputLayer)         (None, 1, 128)            0         
_________________________________________________________________
dense_1 (Dense)              (None, 1, 128)            16512     
_________________________________________________________________
dense_2 (Dense)              (None, 1, 83)             10707     
=================================================================
Total params: 27,219
Trainable params: 27,219
Non-trainable params: 0
_________________________________________________________________
Traceback (most recent call last):
  File "/home/vahideh/PycharmProjects/3KArgen-master/MyTransferClassifier2.py", line 63, in <module>
    history = model.fit((X_Train_3embed, Y_my_Train), epochs=2, batch_size=32)
  File "/home/vahideh/PycharmProjects/MyVirtualEnvs/MyKargo/lib/python3.6/site-packages/keras/engine/training.py", line 1154, in fit
    batch_size=batch_size)
  File "/home/vahideh/PycharmProjects/MyVirtualEnvs/MyKargo/lib/python3.6/site-packages/keras/engine/training.py", line 579, in _standardize_user_data
    exception_prefix='input')
  File "/home/vahideh/PycharmProjects/MyVirtualEnvs/MyKargo/lib/python3.6/site-packages/keras/engine/training_utils.py", line 99, in standardize_input_data
    data = [standardize_single_array(x) for x in data]
  File "/home/vahideh/PycharmProjects/MyVirtualEnvs/MyKargo/lib/python3.6/site-packages/keras/engine/training_utils.py", line 99, in <listcomp>
    data = [standardize_single_array(x) for x in data]
  File "/home/vahideh/PycharmProjects/MyVirtualEnvs/MyKargo/lib/python3.6/site-packages/keras/engine/training_utils.py", line 34, in standardize_single_array
    elif x.ndim == 1:
AttributeError: 'tuple' object has no attribute 'ndim'

如何将这些数据集提供给模型?还是改变模型的输入形状?

【问题讨论】:

  • 删除元组... model.fit(X_Train_3embed, Y_my_Train, epochs=2, batch_size=32)
  • 另一件事不应该是评论中的X_Train_3embed[0].shape 形状(128,)
  • 那么如何训练模型呢?
  • 试试宏是怎么说的
  • '删除元组' 即不将数据集包装在元组中,即不使用元组

标签: python tensorflow keras nlp layer


【解决方案1】:

您的模型输出形状为(None, 1, 83),即每个样本输出为1 x 83,但每个样本的基本事实是一个标量。有两种方法可以解决这个问题

  1. 展平输出并继续使用您的数据
  2. 删除数据中不必要的维度,即将每个样本从 1X128 展平为 128,并更改模型架构以处理一维数据,这将导致输出为一维。

固定代码:

方法一

from keras import Input, Model
from keras.layers import Dense, Flatten
import numpy as np

# Dummy data
X_Train_3embed = np.random.randn(230, 1, 128)
Y_my_Train = np.random.randn(230, 83)

#model
first_input = Input(shape=(1, 128))
first_dense = Dense(128)(first_input)
output_layer = Dense(83, activation='softmax')(first_dense)
outputs = Flatten()(output_layer)

model = Model(inputs=first_input, outputs=outputs)
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['acc'])
model.summary()
model.fit(X_Train_3embed, Y_my_Train, epochs=2, batch_size=32)

输出:

Layer (type)                 Output Shape              Param #   
=================================================================
input_10 (InputLayer)        [(None, 1, 128)]          0         
_________________________________________________________________
dense_18 (Dense)             (None, 1, 128)            16512     
_________________________________________________________________
dense_19 (Dense)             (None, 1, 83)             10707     
_________________________________________________________________
flatten_6 (Flatten)          (None, 83)                0         
=================================================================
Total params: 27,219
Trainable params: 27,219
Non-trainable params: 0
_________________________________________________________________
Epoch 1/2
8/8 [==============================] - 1s 3ms/step - loss: 6.2275 - acc: 0.0162
Epoch 2/2
8/8 [==============================] - 0s 2ms/step - loss: 0.2639 - acc: 0.0150

方法2

# Dummy data
X_Train_3embed = np.random.randn(230, 1, 128)
Y_my_Train = np.random.randn(230, 83)

#model
first_input = Input(shape=(128))
first_dense = Dense(128)(first_input)
outputs = Dense(83, activation='softmax')(first_dense)

model = Model(inputs=first_input, outputs=outputs)
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['acc'])
model.summary()
model.fit(X_Train_3embed.reshape(-1,128), Y_my_Train, epochs=2, batch_size=32)

输出:

Layer (type)                 Output Shape              Param #   
=================================================================
input_13 (InputLayer)        [(None, 128)]             0         
_________________________________________________________________
dense_24 (Dense)             (None, 128)               16512     
_________________________________________________________________
dense_25 (Dense)             (None, 83)                10707     
=================================================================
Total params: 27,219
Trainable params: 27,219
Non-trainable params: 0
_________________________________________________________________
Epoch 1/2
8/8 [==============================] - 0s 2ms/step - loss: -1.1705 - acc: 0.0100
Epoch 2/2
8/8 [==============================] - 0s 2ms/step - loss: -6.3587 - acc: 0.0015

【讨论】:

  • 感谢您的帮助,但问题仍然存在,我注意到模型摘要中的输入形状与您的不同,我的是:input_1 (InputLayer) (None, 1, 128) 0 但您输入中有一个额外的 []:input_10 (InputLayer) [(None, 1, 128)] 0,我应该将其转换为列表吗?
  • 我将 X_Train_3embed 转换为 list by list(X_Train_3embed),但它不起作用:| .pkl 文件是另一个预训练模型的一层的隐藏状态......它们可能不是张量?!我完全糊涂了:(
  • 你能告诉我X_Train_3embed.shape 的输出是什么。同样在方法 1 中,我正在使用您的模型架构,期望我在最后添加了一个展平层。在 keras 中,您不输入张量,而是输入 numpy 数组,框架负责将其转换为张量。另一方面,Pytorch 需要张量。
  • 我注意到问题出现了,因为我在 fit 函数中使用了一个额外的括号! Tnx alot :),所以如果我在输入中添加一个额外的维度:(1,128) -> (1,62, 128),它不起作用,在这种情况下,我应该将 Flatten 层放在 first_dense 之后和 output_layer 之前,对吧?!
  • 您可以让模型使用您想要的任何维度,但在最后一层,因为标签是标量(每个样本),您需要一种机制来将所有这些维度压缩为单个并展平是一种方法它。
【解决方案2】:

基本上 MarcoCerliani 要求您删除元组

您的代码:model.fit((X_Train_3embed, Y_my_Train), epochs=2, batch_size=32)

更改代码:model.fit(X_Train_3embed, Y_my_Train, epochs=2, batch_size=32)

【讨论】:

    猜你喜欢
    • 2020-06-30
    • 2019-01-26
    • 2018-02-10
    • 1970-01-01
    • 1970-01-01
    • 2020-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多