tensorflow - 层 conv1 的输入 0 与层不兼容:预期 ndim=4,发现 ndim=3。收到的完整形状:[None, 256, 3]
问题描述
首先,我知道 NN 正在使用一个数组。这个好像没有关系。
我拥有的是一个 U-Net,一个相当标准的 U-Net。在代码(如下)中,我尝试了生成器并将数据作为数组传递。两种方法都抱怨数据形状错误(见帖子标题)。但我正在传递一个 (None, 256, 256, 3) 数组!如果您指出错误在哪里,我将不胜感激。很可能是一些愚蠢而简单的事情:)代码是一个 Colab 笔记本,它应该从上到下执行,最后一行(“测试”函数)产生错误,真正的问题在 Keras:fit()
代码:我在源和标签文件夹中有图像(现在相同)。
from google.colab import drive
drive.mount("/content/drive/", force_remount=True)
#!pip install -q efficientnet
#import efficientnet.tfkeras as efn
#!pip install livelossplot
#from livelossplot.tf_keras import PlotLossesCallback
import numpy as np
#from sklearn.utils import shuffle
from glob import glob
from pathlib import Path
from shutil import copyfile
import pandas as pd
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
#from tensorflow.keras.utils import Sequence
import sys
import random
#import math
#import numpy as np
#
#import skimage.io
#from skimage.util import img_as_ubyte
#from skimage.util import random_noise
#from skimage.transform import rescale
#from skimage.color import rgb2gray
#from skimage.transform import rotate
#import skimage.filters
#from scipy import ndimage
#
#import matplotlib
import matplotlib.pyplot as plt
#import matplotlib.patheffects as PathEffects
#
import os
from os import listdir
from os.path import isfile, join
#
#import json
#import datetime
##import skimage.draw
#
#import pickle
#
#from copy import copy, deepcopy
#
#import tensorflow as tf
#import tensorflow.keras.layers as Layers
from tensorflow.keras import regularizers
#
from tensorflow.keras.optimizers import Adamax
#
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.preprocessing.image import array_to_img, img_to_array
#
from tensorflow.keras import backend as K
#
from tensorflow.keras.applications.vgg16 import VGG16,preprocess_input
from tensorflow.keras.applications import InceptionResNetV2, Xception, NASNetLarge
#
from mpl_toolkits.mplot3d import Axes3D
from sklearn.manifold import TSNE
#
from tensorflow.keras.layers import Input, Conv2D, MaxPooling2D, Dense, Activation, Dropout, Flatten, Lambda, concatenate, BatchNormalization, GlobalAveragePooling2D, UpSampling2D
#from tensorflow.keras.layers import LeakyReLU
from tensorflow.keras.callbacks import LambdaCallback
#from tensorflow.keras.callbacks import ReduceLROnPlateau, LearningRateScheduler
from tensorflow.keras.callbacks import ModelCheckpoint
#
from tensorflow.keras.models import Model
from tensorflow.keras.models import Sequential
#from sklearn.neighbors import NearestNeighbors
#
#import pylab as pl
import seaborn as sns
#
import cv2
#
##import warnings
##warnings.simplefilter("ignore", category=DeprecationWarning)
##warnings.filterwarnings("ignore")
##os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
#from tensorflow.keras.utils import Sequence
from tensorflow.python.keras.utils.data_utils import Sequence
#%tensorflow_version 1.5
# Is GPU Working?
import tensorflow as tf
print(tf.__version__)
tf.test.gpu_device_name()
working_path = "/content/drive/My Drive/03_unet_selector/"
best_weights_filepath = working_path + "models/03_unet_selector_best.h5"
last_weights_filepath = working_path + "models/03_unet_selector_last.h5"
IMAGE_SIZE = 256
input_shape=(IMAGE_SIZE, IMAGE_SIZE, 3)
BATCH_SIZE = 8
EPOCHS = 20
u_model = 0
TRAINING_IMAGES_PERCENT = 0.6
VALIDATION_IMAGES_PERCENT = 0.2
nL2 = 0.2
opt = tf.keras.optimizers.Adam(0.0001)
def loadImage(path):
img=cv2.imread(str(path)) #, cv2.IMREAD_GRAYSCALE)
img = cv2.resize(img, (IMAGE_SIZE, IMAGE_SIZE))
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
img = img.astype(np.float32)/255.
img = img.reshape(input_shape)
return img
arrLabeledData = []
arrExtensions = ['.jpg','.jpeg','.png', '.gif']
nCount = 0
for strExtension in arrExtensions:
for strImagePath in Path(working_path + "images/inputs/").glob("**/*" + strExtension):
# Get the input image
strImageName = os.path.basename(strImagePath)
# Get corresponding output image (label)
strLabelPath = working_path + "images/labels/" + strImageName
# ---
img_src = loadImage(strImagePath)
img_lbl = loadImage(strLabelPath)
arrLabeledData.append(
{
"src" : strImageName,
"X" : img_src,
"Y" : img_lbl
}
)
# ---
if(nCount % 10 == 0):
print(nCount)
nCount = nCount + 1
nImageIdx = random.randint(0, len(arrLabeledData) - 1)
img_src = loadImage(join(working_path, "images/inputs/", arrLabeledData[nImageIdx]['src']))
img_lbl = loadImage(join(working_path, "images/labels/", arrLabeledData[nImageIdx]['src']))
#img = img.reshape((IMAGE_SIZE, IMAGE_SIZE))
print(arrLabeledData[nImageIdx]['src'])
plt.imshow(img_src) #, cmap='gray')
plt.show()
plt.imshow(img_lbl)
plt.show()
datagen = ImageDataGenerator(
samplewise_center=True,
rotation_range=0,
width_shift_range=0,
height_shift_range=0,
zoom_range=0
)
def deleteSavedNet(best_weights_filepath):
if(os.path.isfile(best_weights_filepath)):
os.remove(best_weights_filepath)
print("deleteSavedNet():File removed")
else:
print("deleteSavedNet():No file to remove")
def plotHistory(history, strParam1, strParam2):
plt.plot(history.history[strParam1], label=strParam1)
plt.plot(history.history[strParam2], label=strParam2)
#plt.title('strParam1')
#plt.ylabel('Y')
#plt.xlabel('Epoch')
plt.legend(loc="best")
plt.show()
def plotFullHistory(history):
arrHistory = []
for i,his in enumerate(history.history):
arrHistory.append(his)
plotHistory(history, arrHistory[0], arrHistory[2])
plotHistory(history, arrHistory[1], arrHistory[3])
def createModel(nL2=0.2, optimizer="adam"):
inputs = keras.Input(shape=(IMAGE_SIZE, IMAGE_SIZE, 3))
conv1 = layers.Conv2D(64, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal', name="conv1")(inputs)
conv1 = layers.Conv2D(64, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal', name="conv1a")(conv1)
pool1 = layers.MaxPooling2D(pool_size=(2, 2), name="pool1")(conv1)
conv2 = layers.Conv2D(128, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal', name="conv2")(pool1)
conv2 = layers.Conv2D(128, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal', name="conv2a")(conv2)
pool2 = layers.MaxPooling2D(pool_size=(2, 2), name="pool2")(conv2)
conv3 = layers.Conv2D(256, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal', name="conv3")(pool2)
conv3 = layers.Conv2D(256, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal', name="conv3a")(conv3)
pool3 = layers.MaxPooling2D(pool_size=(2, 2), name="pool3")(conv3)
conv4 = layers.Conv2D(512, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal', name="conv4")(pool3)
conv4 = layers.Conv2D(512, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal', name="conv4a")(conv4)
drop4 = layers.Dropout(0.5, name="drop4")(conv4)
pool4 = layers.MaxPooling2D(pool_size=(2, 2), name="pool4")(drop4)
conv5 = layers.Conv2D(1024, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal', name="conv5")(pool4)
conv5 = layers.Conv2D(1024, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal', name="conv5a")(conv5)
drop5 = layers.Dropout(0.5, name="drop5")(conv5)
up6 = layers.Conv2D(512, 2, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal', name="up6")(UpSampling2D(size = (2,2))(drop5))
merge6 = layers.concatenate([drop4,up6], axis = 3)
conv6 = layers.Conv2D(512, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal', name="conv6")(merge6)
conv6 = layers.Conv2D(512, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal', name="conv6a")(conv6)
up7 = layers.Conv2D(256, 2, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal', name="up7")(UpSampling2D(size = (2,2), name="up7a")(conv6))
merge7 = layers.concatenate([conv3,up7], axis = 3)
conv7 = layers.Conv2D(256, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal', name="conv7")(merge7)
conv7 = layers.Conv2D(256, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal', name="conv7a")(conv7)
up8 = layers.Conv2D(128, 2, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal', name="up8")(UpSampling2D(size = (2,2), name="up8a")(conv7))
merge8 = layers.concatenate([conv2,up8], axis = 3)
conv8 = layers.Conv2D(128, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal', name="conv8")(merge8)
conv8 = layers.Conv2D(128, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal', name="conv8a")(conv8)
up9 = layers.Conv2D(64, 2, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal', name="up9")(UpSampling2D(size = (2,2), name="up9a")(conv8))
merge9 = layers.concatenate([conv1,up9], axis = 3)
conv9 = layers.Conv2D(64, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal', name="conv9")(merge9)
conv9 = layers.Conv2D(64, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal', name="conv9a")(conv9)
conv9 = layers.Conv2D(3, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal', name="conv10")(conv9)
conv10 = layers.Conv2D(1, 1, activation = 'sigmoid')(conv9)
model = keras.Model(inputs=inputs, outputs=conv10)
model.compile(optimizer = optimizer, loss = keras.losses.BinaryCrossentropy(), metrics = ['accuracy'])
#model.summary()
return model
def gen(bIsTrain):
while True:
arrBatchImages = []
arrBatchLabels = []
for i in range(BATCH_SIZE):
transform_parameters = {
'theta': random.randint(0, 180),
'flip_horizontal': random.randint(0, 1),
'flip_vertical': random.randint(0, 1)
}
if(bIsTrain):
nStart = 0
nEnd = int(len(arrLabeledData) * TRAINING_IMAGES_PERCENT - 1)
else:
nStart = int(len(arrLabeledData) * TRAINING_IMAGES_PERCENT)
nEnd = nStart + int((TRAINING_IMAGES_PERCENT + VALIDATION_IMAGES_PERCENT) - 1)
nImageIdx = random.randint(nStart, nEnd)
img_src = arrLabeledData[nImageIdx]['X']
arrImgSrc = img_to_array(img_src)
arrImgSrc = datagen.apply_transform(arrImgSrc, transform_parameters) #/ 255.
arrImgSrc = np.array(arrImgSrc, dtype="float32")
img_lbl = arrLabeledData[nImageIdx]['Y']
arrImgLbl = img_to_array(img_lbl)
arrImgLbl = datagen.apply_transform(arrImgLbl, transform_parameters) #/ 255.
arrImgLbl = np.array(arrImgLbl, dtype="float32")
arrBatchImages.append(arrImgSrc)
arrBatchLabels.append(arrImgLbl)
yield arrBatchImages, arrBatchLabels
arrNext = next(gen(True))
#print(np.array(arrNext[0]).shape, np.array(arrNext[1]).shape)
plt.imshow(arrNext[0][0])
plt.show()
gen_train = gen(True)
gen_valid = gen(False)
def getCallbacks(monitor, mode):
checkpoint = ModelCheckpoint(best_weights_filepath, monitor=monitor, save_best_only=True, save_weights_only=True, mode=mode, verbose=1)
save_model_at_epoch_end_callback = LambdaCallback(on_epoch_end=lambda epoch, logs: u_model.save_weights(last_weights_filepath))
callbacks_list = [checkpoint, save_model_at_epoch_end_callback] # , early]
return callbacks_list
def loadModel(bBest):
global u_model
if(bBest):
path = best_weights_filepath
strMessage = "load best model"
else:
path = last_weights_filepath
strMessage = "load last model"
if(os.path.isfile(path)):
u_model.load_weights(path)
print(strMessage, ": File loaded")
else:
print(strMessage, ": No file to load")
return u_model
def trainNetwork(EPOCHS, nL2, optimizer, bCumulativeLearning = False):
global u_model
global history
if(bCumulativeLearning == False):
deleteSavedNet(best_weights_filepath)
random.seed(7)
u_model = createModel(nL2, optimizer)
print("Model created")
callbacks_list = getCallbacks("val_accuracy", 'max')
if(bCumulativeLearning == True):
loadModel(u_model, False)
nNumOfTrainSamples = int(len(arrLabeledData) * TRAINING_IMAGES_PERCENT - 1)
STEP_SIZE_TRAIN = nNumOfTrainSamples // BATCH_SIZE
#if(STEP_SIZE_TRAIN < 100):
# STEP_SIZE_TRAIN = 100
nNumOfValidSamples = int(nNumOfTrainSamples * VALIDATION_IMAGES_PERCENT / TRAINING_IMAGES_PERCENT)
STEP_SIZE_VALID = nNumOfValidSamples // BATCH_SIZE
#if(STEP_SIZE_VALID < 100):
# STEP_SIZE_VALID = 100
print(STEP_SIZE_TRAIN, STEP_SIZE_VALID)
print("Available metrics: ", u_model.metrics_names)
# history = u_model.fit(gen_train,
# validation_data=gen_valid, verbose=0,
# epochs=EPOCHS, steps_per_epoch=STEP_SIZE_TRAIN,
# validation_steps=STEP_SIZE_VALID, callbacks=callbacks_list)
# #workers=4,
# #use_multiprocessing=True)
X_train = []
Y_train = []
for nIdx in range(int(len(arrLabeledData) * (TRAINING_IMAGES_PERCENT + VALIDATION_IMAGES_PERCENT))):
X_train.append(arrLabeledData[nIdx]['X'])
Y_train.append(arrLabeledData[nIdx]['Y'])
#np.array(Y_train[0]).shape
u_model.fit(X_train, Y_train, validation_split=STEP_SIZE_VALID / STEP_SIZE_TRAIN, batch_size=BATCH_SIZE, epochs=EPOCHS, callbacks=callbacks_list)
print(nL2)
plotFullHistory(history)
# TBD: here, return best model, not last one
return u_model
def plotAllTestImages():
for nIdx in range(10): #int(len(arrLabeledData) * (TRAINING_IMAGES_PERCENT + VALIDATION_IMAGES_PERCENT)), len(arrLabeledData)):
img_src = arrLabeledData[nIdx]['X']
img_lbl = arrLabeledData[nIdx]['Y']
arrImgSrc = img_src.reshape(1, IMAGE_SIZE, IMAGE_SIZE, 3)
predicts = u_model.predict(arrImgSrc)
img_pred = predicts.reshape(IMAGE_SIZE, IMAGE_SIZE, 3)
f, axarr = plt.subplots(1,2)
axarr[0,0].imshow(img_src)
axarr[0,1].imshow(img_pred)
plt.show()
def test(EPOCHS = EPOCHS, nL2 = nL2, optimizer = optimizer, bCumulativeLearning = False):
global u_model
u_model = trainNetwork(EPOCHS, nL2, optimizer, bCumulativeLearning)
print("loading best model")
u_model = loadModel(u_model, True)
plotAllTestImages()
print(">>> done <<<")
np.random.seed(7)
test(EPOCHS, nL2, opt, False) # **Error is displayed here**
解决方案
看起来问题是使用附加来创建 X_train 和 Y_train。
我会检查它们的形状并尝试使用堆栈来代替,这将在开始时为样本数量添加一个维度。这是一个简化的示例:
a=np.array([[0,1,2],[3,4,5]])
b=np.array([[6,7,8],[9,10,11]])
c=np.stack((a,b)) #shape (2,2,3) with the first 2 representing the number of samples
推荐阅读
- javascript - 理解递归遍历和归约示例
- reactjs - React嵌套路由没有改变
- python-3.x - python中非常大的浮点数
- inno-setup - Inno Setup 在自定义文件夹选择页面上显示安装所需的空间
- php - mailgun-php 错误设置证书验证位置
- java - 带有 OAuth2 和自定义身份验证提供程序的 Spring Boot REST 服务
- c# - 使用 Linq 将十进制字段求和到数据表
- python - 使用 Python 在多个数组中搜索
- javascript - Javascript字符串编码/解码
- ios - 如何在多个 ViewController 中使用 locationManager()