二维输入的Keras模型

时间:2019-01-29 05:24:21

标签: python machine-learning keras

我正在尝试根据房屋价格调整keras tutorial来评估棋盘游戏位置。问题在于棋盘游戏的位置是二维的,这使keras抱怨了。

这是一些基于教程的代码,用于处理从线性方程生成的一些虚拟数据。

import numpy as np
from keras.models import Sequential
from keras.layers import Dense
from keras.wrappers.scikit_learn import KerasRegressor
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import KFold

# fix random seed for reproducibility
seed = 1
np.random.seed(seed)

# Generate dataset with linear outputs.
sample_count = 1000
column_count = 5
X = np.random.uniform(size=sample_count * column_count)
X.shape = (sample_count, column_count)
Y = 2*X[:, 0] + X[:, 1] + X[:, 2] + 11*X[:, 3] + 3*X[:, 4]


# define base model
def baseline_model():
    # create model
    model = Sequential()
    model.add(Dense(column_count * 2,
                    input_dim=column_count,
                    kernel_initializer='normal',
                    activation='relu'))
    model.add(Dense(1, kernel_initializer='normal'))
    # Compile model
    model.compile(loss='mean_squared_error', optimizer='adam')
    return model


# evaluate model with standardized dataset
estimator = KerasRegressor(build_fn=baseline_model, epochs=100, batch_size=5, verbose=0)

kfold = KFold(n_splits=10, random_state=seed)
results = cross_val_score(estimator, X, Y, cv=kfold)
print("Results: %.2f (%.2f) MSE" % (results.mean(), results.std()))

estimator.fit(X, Y)

test_samples = np.identity(column_count)
predictions = estimator.predict(test_samples)
print(predictions)

这很好,但是当我尝试使用与二维数据等效的方法时,效果不佳。这是二维代码:

import numpy as np
from keras.models import Sequential
from keras.layers import Dense
from keras.wrappers.scikit_learn import KerasRegressor
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import KFold

# fix random seed for reproducibility
seed = 1
np.random.seed(seed)

# Generate dataset with linear outputs.
sample_count = 1000
row_count = 2
column_count = 3
X = np.random.uniform(size=sample_count * row_count * column_count)
X = X.reshape(sample_count, row_count, column_count)
Y = 2*X[:, 0, 0] + X[:, 0, 1] + 2*X[:, 0, 2] + 11*X[:, 1, 0] + 3*X[:, 1, 1]
Y = Y.reshape(sample_count, 1)


# define base model
def baseline_model():
    # create model
    model = Sequential()
    model.add(Dense(row_count * column_count * 2,
                    input_shape=(row_count, column_count),
                    kernel_initializer='normal',
                    activation='relu'))
    model.add(Dense(1, kernel_initializer='normal'))
    # Compile model
    model.compile(loss='mean_squared_error', optimizer='adam')
    return model


# evaluate model with standardized dataset
estimator = KerasRegressor(build_fn=baseline_model, epochs=100, batch_size=5, verbose=0)

kfold = KFold(n_splits=10, random_state=seed)
results = cross_val_score(estimator, X, Y, cv=kfold)
print("Results: %.2f (%.2f) MSE" % (results.mean(), results.std()))

estimator.fit(X, Y)

test_samples = np.zeros((row_count*column_count, row_count, column_count))
for sample_num, (row_num, column_num) in enumerate((row_num, column_num)
                                                   for row_num in range(row_count)
                                                   for column_num in range(column_count)):
    test_samples[sample_num, row_num, column_num] = 1
predictions = estimator.predict(test_samples)
print(predictions)

运行该代码时,出现此错误:

Traceback (most recent call last):
  File "/home/don/PycharmProjects/ml_tutorial/ml_tutorial/run_linear2.py", line 40, in <module>
    results = cross_val_score(estimator, X, Y, cv=kfold)
  File "/home/don/.local/share/virtualenvs/ml_tutorial-3a_885qf/lib/python3.6/site-packages/sklearn/model_selection/_validation.py", line 402, in cross_val_score
    error_score=error_score)
  File "/home/don/.local/share/virtualenvs/ml_tutorial-3a_885qf/lib/python3.6/site-packages/sklearn/model_selection/_validation.py", line 240, in cross_validate
    for train, test in cv.split(X, y, groups))
  File "/home/don/.local/share/virtualenvs/ml_tutorial-3a_885qf/lib/python3.6/site-packages/sklearn/externals/joblib/parallel.py", line 917, in __call__
    if self.dispatch_one_batch(iterator):
  File "/home/don/.local/share/virtualenvs/ml_tutorial-3a_885qf/lib/python3.6/site-packages/sklearn/externals/joblib/parallel.py", line 759, in dispatch_one_batch
    self._dispatch(tasks)
  File "/home/don/.local/share/virtualenvs/ml_tutorial-3a_885qf/lib/python3.6/site-packages/sklearn/externals/joblib/parallel.py", line 716, in _dispatch
    job = self._backend.apply_async(batch, callback=cb)
  File "/home/don/.local/share/virtualenvs/ml_tutorial-3a_885qf/lib/python3.6/site-packages/sklearn/externals/joblib/_parallel_backends.py", line 182, in apply_async
    result = ImmediateResult(func)
  File "/home/don/.local/share/virtualenvs/ml_tutorial-3a_885qf/lib/python3.6/site-packages/sklearn/externals/joblib/_parallel_backends.py", line 549, in __init__
    self.results = batch()
  File "/home/don/.local/share/virtualenvs/ml_tutorial-3a_885qf/lib/python3.6/site-packages/sklearn/externals/joblib/parallel.py", line 225, in __call__
    for func, args, kwargs in self.items]
  File "/home/don/.local/share/virtualenvs/ml_tutorial-3a_885qf/lib/python3.6/site-packages/sklearn/externals/joblib/parallel.py", line 225, in <listcomp>
    for func, args, kwargs in self.items]
  File "/home/don/.local/share/virtualenvs/ml_tutorial-3a_885qf/lib/python3.6/site-packages/sklearn/model_selection/_validation.py", line 528, in _fit_and_score
    estimator.fit(X_train, y_train, **fit_params)
  File "/home/don/.local/share/virtualenvs/ml_tutorial-3a_885qf/lib/python3.6/site-packages/keras/wrappers/scikit_learn.py", line 152, in fit
    history = self.model.fit(x, y, **fit_args)
  File "/home/don/.local/share/virtualenvs/ml_tutorial-3a_885qf/lib/python3.6/site-packages/keras/engine/training.py", line 952, in fit
    batch_size=batch_size)
  File "/home/don/.local/share/virtualenvs/ml_tutorial-3a_885qf/lib/python3.6/site-packages/keras/engine/training.py", line 789, in _standardize_user_data
    exception_prefix='target')
  File "/home/don/.local/share/virtualenvs/ml_tutorial-3a_885qf/lib/python3.6/site-packages/keras/engine/training_utils.py", line 128, in standardize_input_data
    'with shape ' + str(data_shape))
ValueError: Error when checking target: expected dense_2 to have 3 dimensions, but got array with shape (900, 1)

如何说服模型接受二维输入?

1 个答案:

答案 0 :(得分:3)

基于GitHub issue中的类似讨论,您可以仅添加Flatten()层以减小输入尺寸。

import numpy as np
from keras.models import Sequential
from keras.layers import Dense, Flatten
from keras.wrappers.scikit_learn import KerasRegressor
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import KFold

# fix random seed for reproducibility
seed = 1
np.random.seed(seed)

# Generate dataset with linear outputs.
sample_count = 1000
row_count = 2
column_count = 3
X = np.random.uniform(size=sample_count * row_count * column_count)
X = X.reshape(sample_count, row_count, column_count)
Y = 2*X[:, 0, 0] + X[:, 0, 1] + 2*X[:, 0, 2] + 11*X[:, 1, 0] + 3*X[:, 1, 1]
Y = Y.reshape(sample_count, 1)


# define base model
def baseline_model():
    # create model
    model = Sequential()
    model.add(Dense(row_count * column_count * 2,
                    input_shape=(row_count, column_count),
                    kernel_initializer='normal',
                    activation='relu'))
    model.add(Flatten())
    model.add(Dense(1, kernel_initializer='normal'))
    # Compile model
    model.compile(loss='mean_squared_error', optimizer='adam')
    return model


# evaluate model with standardized dataset
estimator = KerasRegressor(build_fn=baseline_model, epochs=100, batch_size=5, verbose=0)

kfold = KFold(n_splits=10, random_state=seed)
results = cross_val_score(estimator, X, Y, cv=kfold)
print("Results: %.2f (%.2f) MSE" % (results.mean(), results.std()))

estimator.fit(X, Y)

test_samples = np.zeros((row_count*column_count, row_count, column_count))
for sample_num, (row_num, column_num) in enumerate((row_num, column_num)
                                                   for row_num in range(row_count)
                                                   for column_num in range(column_count)):
    test_samples[sample_num, row_num, column_num] = 1
predictions = estimator.predict(test_samples)
print(predictions)

我认为我需要使用Conv2D之类的其他层才能真正利用二维关系,但这使我摆脱了错误。