给我写一份TensorFlow图像识别水果分类的代码
时间: 2024-03-08 20:38:08 浏览: 95
好的,下面是一份使用TensorFlow实现水果分类的代码:
首先,我们需要导入必要的库和数据集。这里我们使用Kaggle上的“水果360”数据集。
```python
import tensorflow as tf
import os
import numpy as np
import pandas as pd
from sklearn.preprocessing import LabelEncoder
from sklearn.utils import shuffle
from sklearn.model_selection import train_test_split
# 数据集下载链接:https://www.kaggle.com/moltean/fruits
# 下载后解压到当前目录下的"fruits-360"文件夹中
data_dir = "./fruits-360"
# 读取并处理数据
def load_data(data_dir):
fruits = []
labels = []
for fruit_dir in os.listdir(data_dir):
if not fruit_dir.startswith("."):
for image_name in os.listdir(os.path.join(data_dir, fruit_dir)):
if not image_name.startswith("."):
fruits.append(os.path.join(data_dir, fruit_dir, image_name))
labels.append(fruit_dir)
# 将标签转换为数字编码
label_encoder = LabelEncoder()
labels = label_encoder.fit_transform(labels)
# 打乱数据
fruits, labels = shuffle(fruits, labels)
return fruits, labels
fruits, labels = load_data(data_dir)
```
接着,我们需要将数据集分成训练集和测试集,并对图像进行预处理。
```python
# 将数据集划分为训练集和测试集
train_fruits, test_fruits, train_labels, test_labels = train_test_split(fruits, labels, test_size=0.2)
# 定义图像预处理函数
def preprocess_image(image):
image = tf.image.decode_jpeg(tf.io.read_file(image), channels=3)
image = tf.image.resize(image, [224, 224])
image /= 255.0
return image
# 定义数据增强函数
def augment_image(image, label):
image = tf.image.random_flip_left_right(image)
image = tf.image.random_brightness(image, max_delta=0.5)
image = tf.image.random_contrast(image, lower=0.2, upper=0.5)
return image, label
# 使用tf.data构建数据管道
batch_size = 32
train_ds = tf.data.Dataset.from_tensor_slices((train_fruits, train_labels))
train_ds = train_ds.shuffle(buffer_size=len(train_fruits))
train_ds = train_ds.map(lambda x, y: (preprocess_image(x), y))
train_ds = train_ds.map(augment_image)
train_ds = train_ds.batch(batch_size)
test_ds = tf.data.Dataset.from_tensor_slices((test_fruits, test_labels))
test_ds = test_ds.map(lambda x, y: (preprocess_image(x), y))
test_ds = test_ds.batch(batch_size)
```
然后,我们可以使用预训练的ResNet50模型进行迁移学习,并添加自定义的分类层。
```python
# 加载预训练的ResNet50模型
base_model = tf.keras.applications.ResNet50(include_top=False, weights="imagenet", input_shape=(224, 224, 3))
# 冻结预训练模型的权重
base_model.trainable = False
# 添加自定义的分类层
inputs = tf.keras.Input(shape=(224, 224, 3))
x = base_model(inputs, training=False)
x = tf.keras.layers.GlobalAveragePooling2D()(x)
x = tf.keras.layers.Dense(256, activation="relu")(x)
outputs = tf.keras.layers.Dense(131, activation="softmax")(x)
model = tf.keras.Model(inputs, outputs)
```
最后,我们可以使用Adam优化器和交叉熵损失函数进行模型训练。
```python
# 编译模型
model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=1e-3), loss="sparse_categorical_crossentropy", metrics=["accuracy"])
# 训练模型
epochs = 10
history = model.fit(train_ds, epochs=epochs, validation_data=test_ds)
```
完整的代码如下:
```python
import tensorflow as tf
import os
import numpy as np
import pandas as pd
from sklearn.preprocessing import LabelEncoder
from sklearn.utils import shuffle
from sklearn.model_selection import train_test_split
# 数据集下载链接:https://www.kaggle.com/moltean/fruits
# 下载后解压到当前目录下的"fruits-360"文件夹中
data_dir = "./fruits-360"
# 读取并处理数据
def load_data(data_dir):
fruits = []
labels = []
for fruit_dir in os.listdir(data_dir):
if not fruit_dir.startswith("."):
for image_name in os.listdir(os.path.join(data_dir, fruit_dir)):
if not image_name.startswith("."):
fruits.append(os.path.join(data_dir, fruit_dir, image_name))
labels.append(fruit_dir)
# 将标签转换为数字编码
label_encoder = LabelEncoder()
labels = label_encoder.fit_transform(labels)
# 打乱数据
fruits, labels = shuffle(fruits, labels)
return fruits, labels
fruits, labels = load_data(data_dir)
# 将数据集划分为训练集和测试集
train_fruits, test_fruits, train_labels, test_labels = train_test_split(fruits, labels, test_size=0.2)
# 定义图像预处理函数
def preprocess_image(image):
image = tf.image.decode_jpeg(tf.io.read_file(image), channels=3)
image = tf.image.resize(image, [224, 224])
image /= 255.0
return image
# 定义数据增强函数
def augment_image(image, label):
image = tf.image.random_flip_left_right(image)
image = tf.image.random_brightness(image, max_delta=0.5)
image = tf.image.random_contrast(image, lower=0.2, upper=0.5)
return image, label
# 使用tf.data构建数据管道
batch_size = 32
train_ds = tf.data.Dataset.from_tensor_slices((train_fruits, train_labels))
train_ds = train_ds.shuffle(buffer_size=len(train_fruits))
train_ds = train_ds.map(lambda x, y: (preprocess_image(x), y))
train_ds = train_ds.map(augment_image)
train_ds = train_ds.batch(batch_size)
test_ds = tf.data.Dataset.from_tensor_slices((test_fruits, test_labels))
test_ds = test_ds.map(lambda x, y: (preprocess_image(x), y))
test_ds = test_ds.batch(batch_size)
# 加载预训练的ResNet50模型
base_model = tf.keras.applications.ResNet50(include_top=False, weights="imagenet", input_shape=(224, 224, 3))
# 冻结预训练模型的权重
base_model.trainable = False
# 添加自定义的分类层
inputs = tf.keras.Input(shape=(224, 224, 3))
x = base_model(inputs, training=False)
x = tf.keras.layers.GlobalAveragePooling2D()(x)
x = tf.keras.layers.Dense(256, activation="relu")(x)
outputs = tf.keras.layers.Dense(131, activation="softmax")(x)
model = tf.keras.Model(inputs, outputs)
# 编译模型
model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=1e-3), loss="sparse_categorical_crossentropy", metrics=["accuracy"])
# 训练模型
epochs = 10
history = model.fit(train_ds, epochs=epochs, validation_data=test_ds)
```
阅读全文