我的问题是对此question的略微延伸。我有大小 256x256 的图像,我的面具尺寸 65536x4 ,因为我展平了(重新成形的阵列)它我有4个类,因此4。 现在,我想训练U-net进行多级预测。这是我的代码:
import os
import sys
import random
import warnings
import scipy.misc
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from tqdm import tqdm
from itertools import chain
from skimage.io import imread, imshow, imread_collection, concatenate_images, imsave
from skimage.transform import resize
from skimage.morphology import label
import cv2
from keras.models import Model, load_model
from keras.layers import Input
from keras.layers.core import Lambda
from keras.layers.convolutional import Conv2D, Conv2DTranspose
from keras.layers.pooling import MaxPooling2D
from keras.layers.merge import concatenate
from keras.callbacks import EarlyStopping, ModelCheckpoint
from keras import backend as K
from keras import optimizers
from keras.utils import multi_gpu_model
import tensorflow as tf
# Set some parameters
IMG_WIDTH = 256
IMG_HEIGHT = 256
IMG_CHANNELS = 3
mask_dim = 256*256
TRAIN_IM = './train_im/'
TRAIN_MASK = './train_mask/'
num_training = len(os.listdir(TRAIN_IM))
num_test = len(os.listdir(TEST_PATH))
# Get and resize train images
X_train = np.zeros((num_training, IMG_HEIGHT, IMG_WIDTH, IMG_CHANNELS), dtype=np.uint8)
Y_train = np.zeros((num_training, mask_dim, 4), dtype=np.bool)
print('Getting and resizing train images and masks ... ')
sys.stdout.flush()
#load training images
for count, filename in tqdm(enumerate(os.listdir(TRAIN_IM)), total=num_training):
img = imread(os.path.join(TRAIN_IM, filename))[:,:,:IMG_CHANNELS]
img = resize(img, (IMG_HEIGHT, IMG_WIDTH), mode='constant', preserve_range=True)
X_train[count] = img
name, ext = os.path.splitext(filename)
mask_name = name + '_mask' + ext
mask = cv2.imread(os.path.join(TRAIN_MASK, mask_name))[:,:,:1]
mask = np.squeeze(mask)
Y_train[count] = mask
# Build U-Net model
''' ...import VGG16 layers to use pretrained weights...'''
width = 32
c1 = Conv2D(width, (3, 3), activation='elu', padding='same') (s)
c1 = Conv2D(width, (3, 3), activation='elu', padding='same') (c1)
p1 = MaxPooling2D((2, 2)) (c1)
c2 = Conv2D(width*2, (3, 3), activation='elu', padding='same') (p1)
c2 = Conv2D(width*2, (3, 3), activation='elu', padding='same') (c2)
p2 = MaxPooling2D((2, 2)) (c2)
c3 = Conv2D(width*4, (3, 3), activation='elu', padding='same') (p2)
c3 = Conv2D(width*4, (3, 3), activation='elu', padding='same') (c3)
p3 = MaxPooling2D((2, 2)) (c3)
c4 = Conv2D(width*8, (3, 3), activation='elu', padding='same') (p3)
c4 = Conv2D(width*8, (3, 3), activation='elu', padding='same') (c4)
p4 = MaxPooling2D(pool_size=(2, 2)) (c4)
c5 = Conv2D(width*16, (3, 3), activation='elu', padding='same') (p4)
c5 = Conv2D(width*16, (3, 3), activation='elu', padding='same') (c5)
u6 = Conv2DTranspose(width*8, (2, 2), strides=(2, 2), padding='same') (c5)
u6 = concatenate([u6, c4, ll['block4_conv3']])
c6 = Conv2D(width*8, (3, 3), activation='elu', padding='same') (u6)
c6 = Conv2D(width*8, (3, 3), activation='elu', padding='same') (c6)
u7 = Conv2DTranspose(width*4, (2, 2), strides=(2, 2), padding='same') (c6)
u7 = concatenate([u7, c3, ll['block3_conv3']])
c7 = Conv2D(width*4, (3, 3), activation='elu', padding='same') (u7)
c7 = Conv2D(width*4, (3, 3), activation='elu', padding='same') (c7)
u8 = Conv2DTranspose(width*2, (2, 2), strides=(2, 2), padding='same') (c7)
u8 = concatenate([u8, c2, ll['block2_conv2']])
c8 = Conv2D(width*2, (3, 3), activation='elu', padding='same') (u8)
c8 = Conv2D(width*2, (3, 3), activation='elu', padding='same') (c8)
u9 = Conv2DTranspose(width, (2, 2), strides=(2, 2), padding='same') (c8)
u9 = concatenate([u9, c1, ll['block1_conv2']], axis=3)
c9 = Conv2D(width, (3, 3), activation='elu', padding='same') (u9)
c9 = Conv2D(width, (3, 3), activation='elu', padding='same') (c9)
outputs = Conv2DTranspose(1, (1, 1), activation='sigmoid') (c9)
model = Model(inputs=[inputs], outputs=[outputs])
model.compile(optimizer='adam', loss = bce_dice, metrics = ['accuracy'])
model.summary()
earlystopper = EarlyStopping(patience=20, verbose=1)
checkpointer = ModelCheckpoint('model-dsbowl2018-1.h5', verbose=1, save_best_only=True)
results = model.fit(X_train, Y_train, validation_split=0, batch_size=1, epochs=100,
callbacks=[earlystopper, checkpointer])
我怀疑,我无法正确地提供基本事实。但我不知道如何解决这个问题。我究竟如何告诉网络将基础事实的每个维度视为自己的类?
产生的错误如下:
ValueError:无法为Tensor'conv2d_transpose_20_target:0'提供形状值(1,65536,4),其形状为'(?,?,?,?)'
更新
下面接受的答案确实解决了上述问题,但它不允许我使用model.load_weights('model-dsbowl2018-1.h5')
加载权重
因为它给我以下错误:
ValueError:两个形状中的尺寸0必须相等,但是为1和32.形状为[1,1,4,32]和[32,1,1,1]。对于具有输入形状的'Assign_148'(op:'赋值'):[1,1,4,32],[32,1,1,1]。
更新已解决培训多级细分网络时,您必须至少拥有2张图片。单个图像由于某种原因是不够的。 (我只是使用一张图片进行健全性检查)
答案 0 :(得分:1)
根据您的模型架构,您看起来就像是在保留原始图片尺寸,所以看一下您的标签应该是(256,256,4)
尺寸
由于keras在训练时总是除了4维张量之外,因此你的Y_train应该遵循以下维度
Y_train = [batch_size,img_height,img_width,number_of_classes]
查看错误维度(1,65536,4)后传递
1 = batch_size ,65536 flattened image and 4 = num_of_classes
65536
应改为(256, 256)
所以Y_train将是
Y_train = [1,256,256,4]
如果要平整图像,可以使用
平整模型中的图像from keras import backend as K
K.flatten()
因此您应该更改读取图像的代码并执行展平操作,而不是保持图像的空间尺寸。
还有其他观察 您定义输出类数量的层
outputs = Conv2DTranspose(1, (1, 1), activation='sigmoid') (c9)
应该是
outputs = Conv2DTranspose(4, (1, 1), activation='softmax') (c9)
#as you have 4 output classes