首页 > 解决方案 > R keras 说数组没有 conv_2d 的正确尺寸,但它从数组中删除了一个正确的值

问题描述

在制作卷积网络时,keras 采用 c(28,28,1) 的 imput_shape,但是当我运行它进行训练时,它会告诉我它得到的输入是 (6000,28,28)。我了解 keras 输入它自己的数据大小,但为什么它会丢弃它,然后导致它刹车?

问题线(我认为):

model %>%   
  layer_conv_2d(filters = 32, kernel_size = c(3, 3), padding = 'same', input_shape = c(28, 28, 1)) %>%

错误:

Error in py_call_impl(callable, dots$args, dots$keywords) : 
  ValueError: Error when checking input: expected conv2d_5_input to have 4 dimensions, but got array with shape (60000, 28, 28)

代码:

library(keras)
install_keras(tensorflow = "gpu")

mnist <- dataset_mnist()

x_train <- mnist$train$x
y_train <- mnist$train$y
x_test <- mnist$test$x
y_test <- mnist$test$y

# # reshape
#x_train <- array_reshape(x_train, c(nrow(x_train), 784))
#x_test <- array_reshape(x_test, c(nrow(x_test), 784))
# # rescale
# x_train <- x_train / 255
# x_test <- x_test / 255

y_train <- to_categorical(y_train, 10)
y_test <- to_categorical(y_test, 10)
model <- keras_model_sequential() 
model %>%   
  layer_conv_2d(filters = 32, kernel_size = c(3, 3), padding = 'same',  input_shape = c(28, 28, 1)) %>%
  layer_activation('relu') %>%
  # layer_max_pooling_2d(pool_size=c(2, 2), strides=c(2, 2)) %>%
  layer_conv_2d(filters = 16, kernel_size = c(2, 2), dilation_rate = 1, activation = 'softplus', padding = 'same') %>%
  layer_max_pooling_2d(pool_size=c(2, 2)) %>%
  layer_flatten() %>%
  layer_dense(1000, activation = 'relu') %>%
  layer_dropout(0.5) %>%
  layer_dense(10, activation = 'softmax')

  # Stock test model functions
  # layer_dense(units = 256, activation = 'relu', input_shape = c(784)) %>% 
  # layer_dropout(rate = 0.4) %>% 
  # layer_dense(units = 128, activation = 'relu') %>%
  # layer_dropout(rate = 0.3) %>%
  # layer_dense(units = 10, activation = 'softmax') %>%


summary(model)

model %>% compile(
  loss = 'categorical_crossentropy',
  optimizer = optimizer_rmsprop(lr = 0.0001, decay = 1e-6),
  metrics = c('accuracy')
)

history <- model %>% fit(
  x_train, y_train, 
  epochs = 10
)

plot(history)

model %>% evaluate(x_test, y_test)

model %>% predict_classes(x_test)

标签: rtensorflowkeras

解决方案


从以下文档layer_conv_2d

input_shape:- 输入的维度(整数)不包括样本轴。将此层用作模型中的第一层时需要此参数。

所以输入形状(28, 28, 1)意味着 28 行 x 28 列 x 1 个通道。由于图像是黑白的,因此该数据集中只有一个通道。RGB 图像将有 3 个通道。

您收到此错误是因为(60000, 28, 28)缺少第 4 维(通道)的输入形状。你可以通过这样做来解决这个问题:-

x_train <- array_reshape(x_train, dim = c(n_train, 28, 28, 1)) x_test <- array_reshape(x_test, dim = c(n_test, 28, 28, 1))

完整代码:-

library(keras)

mnist <- dataset_mnist()

x_train <- mnist$train$x
y_train <- mnist$train$y
x_test <- mnist$test$x
y_test <- mnist$test$y

n_train <- dim(x_train)[1]
n_test <- dim(x_test)[1]

x_train <- array_reshape(x_train, dim = c(n_train, 28, 28, 1))
x_test <- array_reshape(x_test, dim = c(n_test, 28, 28, 1))

y_train <- to_categorical(y_train, 10)
y_test <- to_categorical(y_test, 10)

model <- keras_model_sequential() 
model %>%   
    layer_conv_2d(filters = 32, kernel_size = c(3, 3), padding = 'same',  input_shape = c(28, 28, 1)) %>%
    layer_activation('relu') %>%
    # layer_max_pooling_2d(pool_size=c(2, 2), strides=c(2, 2)) %>%
    layer_conv_2d(filters = 16, kernel_size = c(2, 2), 
                  dilation_rate = c(1,1), activation = 'softplus', padding = 'same') %>%
    layer_max_pooling_2d(pool_size=c(2, 2)) %>%
    layer_flatten() %>%
    layer_dense(1000, activation = 'relu') %>%
    layer_dropout(0.5) %>%
    layer_dense(10, activation = 'softmax')

summary(model)

model %>% compile(
    loss = 'categorical_crossentropy',
    optimizer = optimizer_rmsprop(lr = 0.0001, decay = 1e-6),
    metrics = c('accuracy')
)

history <- model %>% fit(
    x_train, y_train, 
    epochs = 1
)

plot(history)

model %>% evaluate(x_test, y_test)

model %>% predict_classes(x_test)

推荐阅读