Keras RNN输入维度问题

时间:2018-02-14 03:05:10

标签: keras

我正在尝试使用keras创建一个简单的RNN,但我收到了这个错误:

ValueError: Error when checking input: expected simple_rnn_1_input to have 3 dimensions, but got array with shape (10, 5)

我发现这是一个常见的问题,发现了很多类似的问题,但在我的情况下我仍然无法解决。

代码:

import numpy as np
import glob
from keras.models import Sequential
from keras.layers import SimpleRNN, Dense, Reshape
from keras.preprocessing import sequence

CHARMAP = " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-=!@#$%^&*()_+`~[]\{}|;':\",./<>?"

SEQLEN = 5
BATCHSIZE = 10
ALPHASIZE = len(CHARMAP)
INTERNALSIZE = 512
NLAYERS = 3
learning_rate = 0.001  # fixed learning rate
dropout_pkeep = 0.8    # some dropout
FILES = "shakespeare/*.txt"


## Data related stuff

def char_to_value(char):
    idx = CHARMAP.find(char)
    if idx >= 0:
        return idx
    else:
        return 0

def value_to_char(value):
    return CHARMAP[value]

# iterate every single file
def get_file_data(pattern, index):
    paths = glob.glob(pattern)
    length = len(paths)

    if index < length:
        data = []
        with open(paths[index], "r") as file:
            for line in file:
                line_values = [char_to_value(l) for l in line]
                data = data + list(line_values)
        return data
    else:
        return None

# get batch data in file
def build_line_data(file_data, seqlen, batch_index, batch_count):
    length = len(file_data)
    start = batch_index * batch_count
    end = start+seqlen
    x = []
    y = []
    while end+1 <= length and len(x) < batch_count:
        x_line = file_data[start:end]
        y_line = file_data[start+1:end+1]
        x.append(x_line)
        y.append(y_line)
        start = start + 1
        end = start + seqlen
    x = np.array(x)
    y = np.array(y)
    return x,y


def create_model():
    model = Sequential()
    model.add(SimpleRNN(SEQLEN*ALPHASIZE,input_shape=(SEQLEN, ALPHASIZE)))
    model.compile(optimizer='sgd',loss='binary_crossentropy')
    return model


model = create_model()

for i in range(1):
    file_data = get_file_data(FILES, i)
    idx = 0
    while True:
        x,y = build_line_data(file_data, SEQLEN, idx ,BATCHSIZE)
        model.fit(x, y, epochs=3, batch_size=BATCHSIZE)
        idx = idx + 1
        if 0 == len(x):
            break
        if idx > 10:
            break

响应:

Traceback (most recent call last):
  File "07_rnn.py", line 79, in <module>
    model.fit(x, y, epochs=3, batch_size=BATCHSIZE)
  File "/home/dmabelin/.local/lib/python3.5/site-packages/keras/models.py", line 965, in fit
    validation_steps=validation_steps)
  File "/home/dmabelin/.local/lib/python3.5/site-packages/keras/engine/training.py", line 1593, in fit
    batch_size=batch_size)
  File "/home/dmabelin/.local/lib/python3.5/site-packages/keras/engine/training.py", line 1426, in _standardize_user_data
    exception_prefix='input')
  File "/home/dmabelin/.local/lib/python3.5/site-packages/keras/engine/training.py", line 110, in _standardize_input_data
    'with shape ' + str(data_shape))
ValueError: Error when checking input: expected simple_rnn_1_input to have 3 dimensions, but got array with shape (10, 5)

批次数据:

[[ 0 46 44 41 35]
 [46 44 41 35 38]
 [44 41 35 38 47]
 [41 35 38 47 45]
 [35 38 47 45  0]
 [38 47 45  0 27]
 [47 45  0 27 40]
 [45  0 27 40 30]
 [ 0 27 40 30  0]
 [27 40 30  0 29]]

github链接:https://github.com/djaney/ml-studies/blob/master/07_rnn.py

1 个答案:

答案 0 :(得分:2)

您传递给SimpleRNN图层的ALPHASIZE是一条线索:字母表的大小是预期数据的维度之一。

对于具有一行三个字符的批次,而不是像[[1 4 2]]这样的数组,模型需要一个&#34;一个热的&#34;编码行,每个位置的大小为ALPHASIZE的数组,填充零,但匹配索引为1除外:[[[0 1 0 0 0] [0 0 0 0 1] [0 0 1 0 0]]]

keras.utils中有各种辅助方法可以使您的数据准备更轻松,更快捷。但是,为了简单地修复代码,您可以替换:

while end+1 <= length and len(x) < batch_count:
    x_line = file_data[start:end]
    y_line = file_data[start+1:end+1]

使用:

line = np.zeros((end - start, ALPHASIZE))
while end <= length and len(x) < batch_count:    
    line = np.zeros((end - start, ALPHASIZE))
x_line = line[:-1]
y_line = line[1:]