层conv1的输入0与该层不兼容:预期ndim = 4,找到的ndim = 3。收到完整的图形:[无,256,3]

时间:2020-07-26 11:58:54

标签: tensorflow keras neural-network

首先,我知道NN正在处理数组。这似乎无关。

我拥有的是一个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**

1 个答案:

答案 0 :(得分:0)

问题似乎出在使用append创建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