我想知道我做错了什么。
导入:
import glob
import rasterio as rs
import numpy as np
from matplotlib import pyplot as plt
import tensorflow as tf
from tensorflow import keras as kr
from tensorflow.keras import layers
from tensorflow.python.keras.layers.convolutional import Conv2D
from tensorflow.python.keras.layers.convolutional import MaxPooling2D
from tensorflow.python.keras.metrics import Accuracy, accuracy
有效的代码:
model = kr.Sequential([
kr.layers.Conv2D(32, (2,2), activation='relu', input_shape=(10,10,8)), # output is a 9x9x32 image
kr.layers.Conv2D(64, (4,4), activation='relu'), # output is a 6x6x64 image
kr.layers.MaxPooling2D(3,3), # output is a 2x2x64 image
kr.layers.Conv2D(1024, (2,2), activation='relu'), # output is a 1x1x1024 layer
kr.layers.Dropout(0.5),
kr.layers.Conv2D(3, (1,1), activation=tf.nn.softmax)
])
model.compile(optimizer='Adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
model.fit(train, train_labels, epochs=50)
print("results=",model.evaluate(test, test_labels))
代码抛出错误:
in_shape = (10,10,8)
conv1 = kr.layers.Conv2D(32, (2,2), activation='relu', input_shape=in_shape)(train)
print('shape of 2nd convolution', np.array(conv1).shape)
conv2 = kr.layers.Conv2D(64, (4,4), activation='relu')(conv1)
print('shape of 2nd convolution', np.array(conv2).shape)
pool1 = kr.layers.MaxPooling2D((3,3))(conv2)
print('shape of 1st pool', np.array(pool1).shape)
conv3 = kr.layers.Conv2D(1024, (2,2), activation='relu')(pool1)
print('shape of 3rd convolution', np.array(conv3).shape)
conv4 = kr.layers.Conv2D(3, (1,1), activation=tf.nn.softmax)(conv3)
print('shape of 4th convolution', np.array(conv4).shape)
# M O D E L
model = kr.Sequential([conv1, conv2, pool1, conv3, conv4])
model.compile(optimizer='Adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
model.fit(train, train_labels, epochs=50)
print("results=",model.evaluate(test, test_labels))
错误:
TypeError:添加的层必须是类layer的实例。找到:tf.Tensor
之所以发生这种情况,是因为您将Keras Sequential模型与Keras Functional API混合在一起。
简而言之,当你这样做时:
foo = kr.layers.Conv2D(32, (2,2), activation='relu', input_shape=in_shape)(train)
因为您在指定值(即train
(上使用层,所以存储在foo
中的结果将是张量,如下所示:
秩为4+的张量,表示激活(conv2d(输入,内核(+偏置(。
当您尝试使用Functional API创建模型时,这确实是典型的方法。
然而,正如你得到的错误所表明的那样:
添加的层必须是layer类的实例。找到:tf.Tensor
Keras Sequential模型接受Layer
类的某些内容。问题是,当你这样做时:
model = kr.Sequential([conv1, conv2, pool1, conv3, conv4])
您正在向Sequential模型添加一系列张量。
相反,您想要添加到Sequential模型中的是一个存储Layer的变量,因此您应该这样做:
foo = kr.layers.Conv2D(32, (2, 2), activation="relu", input_shape=in_shape)
[...]
model = kr.Sequential([foo, ...])
注意,在kr.layers.Conv2D
层的末尾没有train
,而foo
变量实际上存储的是层
或者这个:
model = kr.Sequential()
model.add(kr.layers.Conv2D(32, (2, 2), activation="relu", input_shape=in_shape))
[...]
你发布的另一段代码实际上是有效的,因为你确实直接将Layer添加到了序列模型中:
model = kr.Sequential([
kr.layers.Conv2D(32, (2,2), activation='relu', input_shape=(10,10,8)), # output is a 9x9x32 image
kr.layers.Conv2D(64, (4,4), activation='relu'), # output is a 6x6x64 image
kr.layers.MaxPooling2D(3,3), # output is a 2x2x64 image
kr.layers.Conv2D(1024, (2,2), activation='relu'), # output is a 1x1x1024 layer
kr.layers.Dropout(0.5),
kr.layers.Conv2D(3, (1,1), activation=tf.nn.softmax)
])
我能够在https://www.youtube.com/watch?v=pAhPiF3yiXI,我想做的是在keras中实现函数api,其等效代码如下:
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
inp = layers.Input(shape=(10,10,8))
conv1 = layers.Conv2D(32, (2,2), activation='relu')(inp)
conv2 = layers.Conv2D(64, (4,4), activation='relu')(conv1)
pool1 = layers.MaxPooling2D(3,3)(conv2)
conv3 = layers.Conv2D(1024, (2,2), activation='relu')(pool1)
dr_out = layers.Dropout(0.5)(conv3)
out = layers.Conv2D(3, (1,1), activation='softmax')(dr_out)
model = keras.Model(inputs=inp, outputs=out)