我是CNN的初学者。

因此,我正在构建一个二维卷积神经网络,该网络可以预测脑肿瘤类型,并对NumPy阵列有疑问。我的模型的输入形状为(1、512、512),形式为(channels,img_height,img_width)。第四个维度是num_images,它似乎由TensorFlow自动定义。这只是一个快速的背景。我有3064个“ .mat”扩展名文件,其中包含脑肿瘤的MRI扫描。一切都已设置。我将“ .mat”文件转换为numpy矩阵,并将整个矩阵列表附加到单个numpy数组中,以作为CNN的输入传递。我也有相应的标签(将输入传递给模型时索引链接到图像)作为numpy数组。在图像和标签中,所有数字均为浮点型。

同样,我的输入形状为(1、512、512)。但是,在拟合模型时,出现以下错误:

ValueError:检查输入时出错:预期conv2d_130_input具有形状(1,512,512)但具有形状(79,512,512)的数组

因此,我将切片NumPy数组以创建train_images,train_labels,test_images和test_labels。我已经验证了带有标签匹配的每个训练集和测试集的长度。它们也是数组,我检查了多次。这是一个值错误。那么,我该如何解决呢?

我什至不知道输入形状在哪里(79,512,512)。我有一个循环将f“ {n} .mat”图像转换为矩阵。我正在使用100张图片进行测试,并进行了80次训练和20次测试。我认为这里是错误的,输入形状是(channels,img-hght,img-wdth),但是要训练的图像数量却被放置在通道的值中。因此,输入被放置为(num_images,img-hght,img-wdth)。这是错误的,应该更改,但是我不知道该怎么做。或者,我可能错了,我的发言可能没有道理。我正在提供所有代码,并在Colab上运行它。如果您下载代码并希望运行它,请确保更改图像路径,以帮助我。非常感谢!

数据集:https://figshare.com/articles/brain_tumor_dataset/1512427/5

#Importing the necessary libraries through PIP to the Virtual Environment
try:
  !python -m pip install --upgrade pip #Quickly update PIP to latest version
  !python -m pip install pymatreader
  !python -m pip install pyswarm #An interesting library for testing purposes
  print("""
The following libraries are available and have been successfully fetched:
  >>> PyMatReader
  >>> Particle Swarm""")
except Exception:
  print("""
The following libraries have unavailable and have not been fetched:
  >>> PyMatReader
  >>> Particle Swarm""")
  pass


#Importing the necessary libraries to the Virtual Environment
from __future__ import absolute_import, division, print_function, unicode_literals
import random as rnd
from random import shuffle
import numpy as np
import sys
import scipy as sp
from scipy.ndimage import gaussian_filter
import pymatreader as pym
import pandas as pd
import seaborn as sns
import matplotlib as mpl
import matplotlib.image as mplimg
import matplotlib.pyplot as plt
import PIL
from PIL import Image
import imageio
import sklearn as sk
from sklearn.model_selection import train_test_split
from sklearn.feature_extraction import image
import sklearn.metrics as skm

print("""
The following libraries have been successfully imported:
  >>> Future
  >>> Random (with shuffle)
  >>> NumPy
  >>> System
  >>> SciPy (with gaussian filter)
  >>> PyMatReader
  >>> Pandas
  >>> Seaborn
  >>> Matplotlib (with PyPlot & Image)
  >>> PIL (with Image)
  >>> Imageio
  >>> Sci-Kit Learn (with metrics & train_test_split)
  >>> Sci-kit Learn Feature Extraction (with Image)
""")

try:
  %tensorflow_version 2.x
  import keras
  import tensorflow as tf
  print("TensorFlow version 2.x is available and has been successfully imported.")
except Exception:
  %tensorflow_version 1.x
  import keras
  import tensorflow as tf
  print("TensorFlow version 2.x is unavailable. TensorFlow version 1.x has been imported instead.")
  pass

from tensorflow.keras import datasets, layers, models
import keras.preprocessing
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Conv2D, Flatten, Dropout, MaxPooling2D
from keras.optimizers import Adam
import pyswarm
from pyswarm import pso

autoTune = tf.data.experimental.AUTOTUNE

print("""
The following deep learning optimizers have been successfully imported:
  >>> Adam
  >>> Particle Swarm (with pso)
""")

print("All libraries have been successfully imported.")


#Understanding the Image Data using Seaborn and Matplotlib
classNames = {1 : "Meningioma", 2 : "Glioma", 3 : "Pituitary Tumor", 4 : "Unkown", 5 : "Unkown"}
outputSize = len(classNames)

chooseImgNum = 2978
example = pym.read_mat(f'/content/gdrive/My Drive/My Files/Neuroimaging/Neuroimaging Datasets/MATLAB Files/{chooseImgNum}.mat')
cjdata = example['cjdata']
pid = cjdata['PID']
img = cjdata['image']
label = cjdata['label']

tumorBorder = cjdata['tumorBorder']
tumorMask = cjdata['tumorMask']
print("Tumor Border is: \n", tumorBorder, "\n")
print("Tumor Mask is: \n", tumorMask, "\n")

def printImage():
  plt.figure(figsize=(5, 5))
  plt.imshow(img, cmap=None)

def matrixConv(): #Data Visualization only
  matrix = np.asmatrix(tumorBorder)
  plt.figure(figsize=(5, 5))
  return matrix

def applyGrayscale():
  plt.figure(figsize=(5, 5))
  plt.imshow(img, cmap='gray')

print("""
      Below is the original image followed by a grayscale application:
____________________________________________________________________________
""")

printImage()
applyGrayscale()


#Preprocessing Brain Images from Dataset
range1 = np.arange(0, 100)
imgMatrices = []
imgNum = 1
i = 1

while imgNum in range1:
  imgNum = pym.read_mat(f'/content/gdrive/My Drive/My Files/Neuroimaging/Neuroimaging Datasets/MATLAB Files/{imgNum}.mat')
  cjdata = imgNum['cjdata']
  imgMatrix = cjdata['image']
  # plt.figure(figsize=(5, 5))
  # plt.imshow(image_matrix, cmap='gray')
  imgMatrixNP = np.asmatrix(imgMatrix)
  imgArrayNP = np.asarray(imgMatrixNP)
  imgMatrices.append(imgArrayNP)
  imgNum = i
  i = i + 1

print("The length of the image input list is:", len(imgMatrices))

imgMatricesNP = np.asarray(imgMatrices)
print("The length of the converted image input array is:", len(imgMatricesNP), "\n")

print("The image input array:")
imgMatricesNP #Prints the raw array


#Supervised Learning: Understanding Cancer Type labels
np.set_printoptions(threshold=3)
#np.set_printoptions(threshold=sys.maxsize) #To check the content of the entire array

rawMatData = pym.read_mat('/content/gdrive/My Drive/My Files/Neuroimaging/Neuroimaging Datasets/cvind.mat')
print("Labels file in \".mat\" format converted to dictionary format:", rawMatData)

matDataList = list(rawMatData.values())
print("Labels converted to list format:", matDataList)

matDataArray = np.asarray(matDataList)
print("Labels converted to array format:", matDataArray, "\n")
shapedMatDataArray = matDataArray.reshape(-1, 3064, 1)
print("Reshaped labels in array format:\n", shapedMatDataArray, "\n")

matData = pd.DataFrame(matDataArray)
print("Labels converted to a Pandas DataFrame:")
matData #Prints out the DataFrame


#Viewing labels based on image number
def imgLabelCheck(n):
  callback = matData.at[0, n-1]
  print(f"Image Number {n} has the following Cancer Type: {classNames[callback]}.")
  return

pickImg = 1 #Choose an image number to look for its Cancer Type
imgLabelCheck(pickImg)


#Preparing the Datasets: Looping Train Set & Test Set
print("___________________________________________________________________________________\n")

train_images = np.array([imgMatricesNP[0:79]])
print("Training images range is:\n", train_images, "\n")

uppTrBn = len(train_images)
loqTrRng = 0
uppTrRng = 79
train_labels = np.asarray(matData.loc[:, loqTrRng:uppTrRng], dtype=float, order='A')
print("Training labels range is:", train_labels)

print("___________________________________________________________________________________\n")

test_images = np.array([imgMatricesNP[80:100]])
print("Testing images range is: \n", test_images, "\n")

uppTsBn = len(test_images)
loqTsRng = 80
uppTsRng = 100
test_labels = np.asarray(matData.loc[:, loqTsRng:uppTsRng], dtype=float, order='A')
print("Testing labels range is:", test_labels)

print("___________________________________________________________________________________")
#train_labels #Verify if the ranges are in fact NumPy arrays
#test_labels


#Defining the Convolutional Neural Network
model = models.Sequential()

model.add(layers.Conv2D(512, (3, 3), activation='relu', data_format="channels_first", input_shape=(1, 512, 512))) #The Input Layer
#model.add(layers.Dropout(0.5, noise_shape=None, seed=None)) #Optional Dropout Layer

model.add(layers.MaxPooling2D((2, 2), padding='same')) #MaxPooling Layer 1
model.add(layers.Conv2D(1024, (3, 3), activation='relu', padding='same')) #Hidden Convolutional Layer 1
model.add(layers.Dropout(0.5, noise_shape=None, seed=None)) #Optional Dropout Layer

model.add(layers.MaxPooling2D((2, 2), padding='same')) #MaxPooling Layer 2
model.add(layers.Conv2D(1024, (3, 3), activation='relu', padding='same')) #Hidden Convolutional Layer 2
#model.add(layers.Dropout(0.5, noise_shape=None, seed=None)) #Optional Dropout Layer

model.add(layers.MaxPooling2D((2, 2), padding='same')) #MaxPooling Layer 3
model.add(layers.Conv2D(1024, (3, 3), activation='relu', padding='same')) #Hidden Convolutional Layer 3
model.add(layers.Dropout(0.5, noise_shape=None, seed=None)) #Optional Dropout Layer

model.add(layers.MaxPooling2D((2, 2), padding='same')) #MaxPooling Layer 4
model.add(layers.Conv2D(1024, (3, 3), activation='relu', padding='same')) #Hidden Convolutional layer 4
#model.add(layers.Dropout(0.5, noise_shape=None, seed=None)) #Optional Dropout Layer

model.add(layers.MaxPooling2D((2, 2), padding='same')) #MaxPooling Layer 5
model.add(layers.Conv2D(1024, (3, 3), activation='relu', padding='same')) #Hidden Convolutional Layer 5
model.add(layers.Dropout(0.5, noise_shape=None, seed=None)) #Optional Dropout Layer

model.add(layers.MaxPooling2D((2, 2), padding='same')) #MaxPooling Layer 6
model.add(layers.Conv2D(1024, (3, 3), activation='relu', padding='same')) #Hidden Convolutional Layer 6
#model.add(layers.Dropout(0.5, noise_shape=None, seed=None)) #Optional Dropout Layer

model.add(layers.Flatten()) #The Flattening Layer

model.add(layers.Dense(512, activation='relu')) #Dense Layer 1
model.add(layers.Dense(256, activation='relu')) #Dense Layer 2
model.add(layers.Dense(128, activation='relu')) #Dense Layer 3
model.add(layers.Dense(64, activation='relu')) #Dense Layer 4
model.add(layers.Dense(32, activation='relu')) #Dense Layer 5
model.add(layers.Dense(16, activation='relu')) #Dense Layer 6

model.add(layers.Dense(outputSize, activation='softmax')) #The Output Layer

model.summary()


#Compiling the Convolutional Neural Network with an Optimizer
#The Adam Optimizer is ideal for biological image classification.
#The Optimizer automatically performs forward and backward propagation.

model.compile(
    optimizer='Adam',
    loss='sparse_categorical_crossentropy',
    metrics=['accuracy'],
    loss_weights=None,
    sample_weight_mode=None,
    weighted_metrics=None,
    target_tensors=None
  )

print("The Neuroimaging Model has been successfully compiled.")


#Training the Convolutional Neural Network
history = model.fit(train_images, train_labels, epochs=10, batch_size=1, verbose=1,
                    validation_data=(test_images, test_labels))

print("\nThe Neuroimaging Model has been successfully trained.")


此页面上的每个代码框都代表Colab或Jupyter笔记本的单个代码单元。再次欢迎和感谢所有帮助! (该模型尚未完全构建,但添加了图层仅用于实验。

最佳答案

添加行:

train_images = np.reshape(train_images, (-1,1,512,512))


在代码中的以下行之后

train_images = np.array([imgMatricesNP[0:79]])


获取单个图像的input_shape=(1, 512, 512)而不是(79, 512, 512),因为模型期望输入形状为(1, 1, 512, 512)(根据尺寸(batch_size,通道,高度,宽度)),而当前代码提供的输入形状为(1, 79, 512, 512)。如果您有足够的计算资源,请将batch_size增加到8(例如),这样您的总输入形状将为(8, 1, 512, 512)

另外,对test_images执行类似的操作:

test_images = np.reshape(test_images, (-1,1,512,512))


行后:

test_images = np.array([imgMatricesNP[80:100]])


PS:另外,看来您的意图是从输入imgMatricesNP中分割前80张图像。但是,使用imgMatricesNP[0:79]时,您只会获得前79个图像(因为片中的最后一个索引在Python中不包含在内)。因此,更正为:

train_images = np.array([imgMatricesNP[0:80]])


并分配uppTrRng=80

希望这可以帮助! :)

关于python - 如何解决:ValueError:检查输入时出错:预期conv2d_130_input具有形状(1、512、512),但数组的形状为(79、512、512),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/60133220/

10-12 16:33