Tensorflow CNN图像回归

Tensorflow CNN图像回归,tensorflow,regression,conv-neural-network,tflearn,Tensorflow,Regression,Conv Neural Network,Tflearn,我眼前的问题是,我尝试过的各种CNN回归模型总是返回相同(或非常相似)的值,我试图找出原因。但我愿意接受各种各样的建议 我的数据集如下所示: x:64x64灰度图像排列成64 x 64 x n阵列 y:介于0和1之间的值,每个值对应一个图像(将其视为某种比例) 天气:拍摄每张图像时的4个天气读数(环境温度、湿度、露点、气压) 目标是使用图像和天气数据预测y。因为我在处理图像,所以我认为CNN是合适的(如果这里有其他策略,请告诉我) 据我所知,CNN最常用于分类任务——将其用于回归是相当罕见的

我眼前的问题是,我尝试过的各种CNN回归模型总是返回相同(或非常相似)的值,我试图找出原因。但我愿意接受各种各样的建议

我的数据集如下所示:

  • x
    :64x64灰度图像排列成64 x 64 x n阵列
  • y
    :介于0和1之间的值,每个值对应一个图像(将其视为某种比例)
  • 天气
    :拍摄每张图像时的4个天气读数(环境温度、湿度、露点、气压)
目标是使用图像和天气数据预测
y
。因为我在处理图像,所以我认为CNN是合适的(如果这里有其他策略,请告诉我)

据我所知,CNN最常用于分类任务——将其用于回归是相当罕见的。但从理论上讲,它应该不会有太大的不同——我只需要将损失函数更改为MSE/RMSE,将最后一个激活函数更改为线性(尽管这里可能更适合使用sigmoid,因为
y
介于0和1之间)

我遇到的第一个障碍是试图找出如何合并天气数据,自然的选择是将它们合并到第一个完全连接的层中。我在这里找到了一个例子:

我遇到的第二个障碍是确定架构。通常我只会选择一张纸,复制它的结构,但我在CNN图像回归上找不到任何东西。所以我尝试了一个(相当简单的)有3个卷积层和2个完全连接层的网络,然后从

现在我遇到的问题是,我尝试的所有模型都输出相同的值,即训练集的平均值
y
。看看tensorboard,损失函数相当快地变平(大约25个时代之后)。你知道这是怎么回事吗?虽然我确实了解每个层的基本功能,但对于如何为特定的数据集或任务创建一个好的体系结构,我没有直觉

这里有一个例子。我正在使用tflearn示例页面中的VGNET:

tf.reset_default_graph()

img_aug = ImageAugmentation()
img_aug.add_random_flip_leftright()
img_aug.add_random_flip_updown()
img_aug.add_random_90degrees_rotation(rotations=[0, 1, 2, 3])

convnet = input_data(shape=[None, size, size, 1], 
                     data_augmentation=img_aug, 
                     name='hive')
weathernet = input_data(shape=[None, 4], name='weather')

convnet = conv_2d(convnet, 64, 3, activation='relu', scope='conv1_1')
convnet = conv_2d(convnet, 64, 3, activation='relu', scope='conv1_2')
convnet = max_pool_2d(convnet, 2, strides=2, name='maxpool1')

convnet = conv_2d(convnet, 128, 3, activation='relu', scope='conv2_1')
convnet = conv_2d(convnet, 128, 3, activation='relu', scope='conv2_2')
convnet = max_pool_2d(convnet, 2, strides=2, name='maxpool2')

convnet = conv_2d(convnet, 256, 3, activation='relu', scope='conv3_1')
convnet = conv_2d(convnet, 256, 3, activation='relu', scope='conv3_2')
convnet = conv_2d(convnet, 256, 3, activation='relu', scope='conv3_3')
convnet = max_pool_2d(convnet, 2, strides=2, name='maxpool3')

convnet = conv_2d(convnet, 512, 3, activation='relu', scope='conv4_1')
convnet = conv_2d(convnet, 512, 3, activation='relu', scope='conv4_2')
convnet = conv_2d(convnet, 512, 3, activation='relu', scope='conv4_3')
convnet = max_pool_2d(convnet, 2, strides=2, name='maxpool4')

convnet = conv_2d(convnet, 512, 3, activation='relu', scope='conv5_1')
convnet = conv_2d(convnet, 512, 3, activation='relu', scope='conv5_2')
convnet = conv_2d(convnet, 512, 3, activation='relu', scope='conv5_3')
convnet = max_pool_2d(convnet, 2, strides=2, name='maxpool5')

convnet = fully_connected(convnet, 4096, activation='relu', scope='fc6')
convnet = merge([convnet, weathernet], 'concat')
convnet = dropout(convnet, .75, name='dropout1')

convnet = fully_connected(convnet, 4096, activation='relu', scope='fc7')
convnet = dropout(convnet, .75, name='dropout2')

convnet = fully_connected(convnet, 1, activation='sigmoid', scope='fc8')

convnet = regression(convnet, 
                     optimizer='adam', 
                     learning_rate=learning_rate, 
                     loss='mean_square', 
                     name='targets')

model = tflearn.DNN(convnet, 
                    tensorboard_dir='log', 
                    tensorboard_verbose=0)

model.fit({
            'hive': x_train,
            'weather': weather_train  
          },
          {'targets': y_train}, 
          n_epoch=1000, 
          batch_size=batch_size,
          validation_set=({
              'hive': x_val,
              'weather': weather_val
          }, 
                          {'targets': y_val}), 
          show_metric=False, 
          shuffle=True,
          run_id='poop')
要了解我的对象是什么,请执行以下操作:

  • x\u列车
    是一个形状的标准阵列
    (n,64,64,1)
  • weather\u train
    是一列形状的标准
    (n,4)
  • y\u列
    是一列形状
    (n,1)

过度拟合是另一个问题,但考虑到模型在训练集上表现不佳,我想我可以稍后再考虑。

解决您对测试集中所有实例的预测值相同的问题。这里有几个选项不涉及更改conv网络的结构:

  • 您可以使用sklearn
    StandardScaler()
    重新缩放目标变量(它通过删除平均值并缩放到单位方差来标准化特征)
  • 缩放像素数据;一般来说,性能会随着像素数据的缩放而提高,因为经验法则总是将像素数据除以255.0(如本文末尾所示)
  • 你可以利用学习率和误差函数(CNN为所有预测输出相同值的原因是因为它确定的是最小误差点)
  • 下一步。如果您试图执行回归请确保最终完全连接的层使用线性激活函数,而不是sigmoid。线性激活函数将神经元的输入乘以神经元权重,并创建与输入成比例的输出

    convnet=完全连接(convnet,1,activation='linear',scope='fc8')

    最后。我最近在Keras中为回归任务实施了ResNet50。这是该网络的结构,该版本不允许加载预训练权重,它必须接收形状图像(2242243)

    可以使用一些x_列、x_测试、y_列、y_测试数据(其中x_列/测试是图像数据,y_列、y_测试数据是间隔[0,1]上的数值)来实现

    scaler = MinMaxScaler()
    images = load_images(df=target, path=PATH_features, resize_shape=(224, 224), quadruple=True)
    images = images / 255.0  # scale pixel data to [0, 1]
    images = images.astype(np.float32)
    imshape = images.shape
    
    target = target[Target]
    target = quadruple_target(target, target=Target)
    
    x_train, x_test, y_train, y_test = train_test_split(images, target, test_size=0.3, random_state=101)
    
    y_train = scaler.fit_transform(y_train)
    y_test = scaler.transform(y_test)
    
    model = resnet50(imshape[1], imshape[2], imshape[3], nodes=256)
    
    opt = Adam(lr=1e-5, decay=1e-5 / 200)
    model.compile(loss=lossFN, optimizer=opt)
    
    history = model.fit(x_train, y_train, validation_data=(x_test, y_test), verbose=1, epochs=200)
    
    pred = model.predict(x_test)
    

    您上一个完全连接的层将
    sigmoid
    设置为其激活功能。这通常仅在您想要执行分类时使用。我会尝试其他激活功能,例如
    relu
    。是的,我尝试了
    sigmoid
    linear
    relu
    ,用于最后一个完全连接的层。我知道de>linear是回归任务中最常见的,但由于响应从来都不是负的,我认为
    relu
    可能也会起作用,而且由于响应总是在0和1之间,
    sigmoid
    似乎也有点合适。您找到了问题的解决方案吗?我对答案感兴趣
    scaler = MinMaxScaler()
    images = load_images(df=target, path=PATH_features, resize_shape=(224, 224), quadruple=True)
    images = images / 255.0  # scale pixel data to [0, 1]
    images = images.astype(np.float32)
    imshape = images.shape
    
    target = target[Target]
    target = quadruple_target(target, target=Target)
    
    x_train, x_test, y_train, y_test = train_test_split(images, target, test_size=0.3, random_state=101)
    
    y_train = scaler.fit_transform(y_train)
    y_test = scaler.transform(y_test)
    
    model = resnet50(imshape[1], imshape[2], imshape[3], nodes=256)
    
    opt = Adam(lr=1e-5, decay=1e-5 / 200)
    model.compile(loss=lossFN, optimizer=opt)
    
    history = model.fit(x_train, y_train, validation_data=(x_test, y_test), verbose=1, epochs=200)
    
    pred = model.predict(x_test)