from tensorflow.keras.applications.vgg16 import VGG16
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Conv2D,MaxPool2D,Activation,Dropout,Flatten,Dense
from tensorflow.keras.optimizers import SGD
from tensorflow.keras.preprocessing.image import ImageDataGenerator,img_to_array,load_img
import numpy as np
import tensorflow as tf
import pathlib
train_data_dir =pathlib.Path('D:/pythonpython/tensorflow/model/data/train')
test_data_dir =pathlib.Path('D:/pythonpython/tensorflow/model/data/test')
train_data_root = pathlib.Path(train_data_dir)
test_data_root = pathlib.Path(test_data_dir)
print(train_data_root)
print(test_data_root)
import random
all_image_paths = list(train_data_root.glob('/')) # 所有子目录下图片
all_image_paths = [str(path) for path in all_image_paths]
random.shuffle(all_image_paths) #打乱数据
print(len(all_image_paths))
train_label_names = sorted(item.name for item in train_data_root.glob('/') if item.is_dir())#读取目录并排序为类别名
train_label_to_index = dict((name, index) for index, name in enumerate(train_label_names))#创建类别字典
train_all_image_labels = [train_label_to_index[pathlib.Path(path).parent.name]
for path in all_image_paths] #图像parent path 对应类
test_label_names = sorted(item.name for item in test_data_root.glob('/') if item.is_dir())#读取目录并排序为类别名
test_label_to_index = dict((name, index) for index, name in enumerate(test_label_names))#创建类别字典
test_all_image_labels = [test_label_to_index[pathlib.Path(path).parent.name]
for path in all_image_paths] #图像parent path 对应类
train_label_to_index
test_label_to_index
@tf.function
def preprocess_image(path):
image_size=224
image = tf.io.read_file(path)
image = tf.image.decode_jpeg(image, channels=3)
image = tf.image.resize(image, [image_size, image_size])
image /= 255.0 # normalize to [0,1] range
return image
ds = tf.data.Dataset.from_tensor_slices((all_image_paths, train_all_image_labels)
)
def load_and_preprocess_from_path_label(path, label):
return preprocess_image(path), label
image_label_ds = ds.map(load_and_preprocess_from_path_label)
image_label_ds
AUTOTUNE = tf.data.experimental.AUTOTUNE
BATCH_SIZE = 16
image_count = len(all_image_paths)
ds = image_label_ds.shuffle(buffer_size=image_count) # buffer_size等于数据集大小确保充分打乱
ds = ds.repeat() #repeat 适用于next(iter(ds)
)
ds = ds.batch(BATCH_SIZE)
prefetch
使数据集在后台取得 batch。ds = ds.prefetch(buffer_size=AUTOTUNE)#随机缓冲区相关
vgg16_model = VGG16(weights='imagenet',include_top=False, input_shape=(224,224,3)
)
vgg16_model.summary()
top_model = Sequential()
top_model.add(Flatten(input_shape=vgg16_model.output_shape[1:])
)
top_model.add(Dense(256,activation='relu'))
top_model.add(Dropout(0.5))
top_model.add(Dense(5,activation='softmax')
)
model = Sequential()
model.add(vgg16_model)
model.add(top_model)
def change_range(image,label):
return 2*image-1, label
keras_ds = ds.map(change_range)
image_batch, label_batch = next(iter(keras_ds)
)
feature_map_batch = vgg16_model(image_batch)
print(feature_map_batch.shape)
steps_per_epoch=tf.math.ceil(len(all_image_paths)/BATCH_SIZE).numpy()
steps_per_epoch
model.compile(optimizer=SGD(lr=1e-3,momentum=0.9),loss='sparse_categorical_crossentropy',metrics=['accuracy'])
history=model.fit(ds, epochs=16, steps_per_epoch=230)
model.save('model_vgg16.h5')
test_data_path = 'D:/pythonpython/tensorflow/model/data/test/dandelion/dandelion-5.jpg'
img_height =224
img_width = 224
img = tf.keras.utils.load_img(
test_data_path, target_size=(img_height, img_width)
)
img_array = tf.keras.utils.img_to_array(img)
img_array = tf.expand_dims(img_array, 0) # Create a batch
predictions = model.predict(img_array)
score = tf.nn.softmax(predictions[0])
print(
This image most likely belongs to {} with a {:2f} percent confidence.
.format(test_label_names[np.argmax(score)], 100 * np.max(score))
)
from tensorflow.keras.models import load_model
import numpy as np
import matplotlib.pyplot as plt
label = test_label_to_index
label = dict(zip(label.values(),label.keys()
)
)
model = load_model('model_vgg16.h5')
@tf.function
def predict(image):
# 导入图片
image = load_img(image)
plt.imshow(image)
plt.show()
image = image.resize((224,224))
image = img_to_array(image)
image = image/255
# (1,224,224,3)
image = np.expand_dims(image,0)
return model.predict_classes(image)[0]
pre = predict("D:/pythonpython/tensorflow/model/data/test/dandelion/dandelion-5.jpg")
print(label[pre])
但是出现错误
python
AttributeError: 'Sequential' object has no attribute 'predict_classes'
tensorflow版本2.6,找不到可以替代的方法
python
This image most likely belongs to dandelion with a () percent confidence.
模型预测的准确率一般都是以一个batch或epoch来评估的,并没有预测某条数据的准确率,只有预测某条数据的标签。
看到你代码的报错信息,model.predict_classes
这个方法并不存在,需要自行实现。
2.6版本之后Model已经取消了predict_classes
predict_classes方法仅适用于Sequential类
也就是你的代码中
top_model = Sequential()
model = Sequential()
出错代码 load_model获取的是Model类
model = load_model('model_vgg16.h5')
所以你这行代码return model.predict_classes(image)[0]出错了,因为没有这个方法。
对于Model类,你可以使用predict方法,该方法提供一个概率向量,然后获得该向量的argmax(使用np.argmax(y_pred1,axis=1))。
predict_x=model.predict(image)
return np.argmax(image,axis=0)
这个网站针对你这个问题有很多解决方案:https://stackoverflow.com/questions/68836551/keras-attributeerror-sequential-object-has-no-attribute-predict-classes
需要修改预测实现的代码