Tensorflow CNN图像回归
我眼前的问题是,我尝试过的各种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最常用于分类任务——将其用于回归是相当罕见的
:64x64灰度图像排列成64 x 64 x n阵列x
:介于0和1之间的值,每个值对应一个图像(将其视为某种比例)y
:拍摄每张图像时的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网络的结构:
StandardScaler()
重新缩放目标变量(它通过删除平均值并缩放到单位方差来标准化特征)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)