gl2222

复制代码
import os
import numpy as np
import pandas as pd
import tensorflow as tf
from keras.applications.inception_v3 import InceptionV3
from keras.layers import Dense, Flatten, Concatenate, Input
from keras.models import Model
from tensorflow.keras.optimizers import Adam
from keras.callbacks import EarlyStopping, ReduceLROnPlateau
from keras.preprocessing import image
from sklearn.model_selection import train_test_split

# 定义超参数
IMG_WIDTH, IMG_HEIGHT = 500, 500
BATCH_SIZE = 32
EPOCHS = 300
LEARNING_RATE = 0.001

# 输入参数:图像文件目录和骨龄信息CSV文件路径
images_dir = r'D:\python_code\Bone-Age-Assessment-master\train'
boneage_info_path = r'D:\boneage_data\boneage-training-dataset.csv'

# 读取骨龄信息CSV文件
boneage_info = pd.read_csv(boneage_info_path)

# 确保id列的值为字符串类型
boneage_info['ID'] = boneage_info['ID'].astype(str)

# 使用 sklearn 自动划分训练集和验证集
train_boneage_info, val_boneage_info = train_test_split(boneage_info, test_size=0.2, random_state=42)

# 创建一个ImageDataGenerator用于加载和预处理图像
datagen = tf.keras.preprocessing.image.ImageDataGenerator(
    rescale=1. / 255,
    rotation_range=20,
    width_shift_range=0.2,
    height_shift_range=0.2,
    zoom_range=0.2,
    horizontal_flip=True
)


# 自定义生成器类
class CustomDataGenerator(tf.keras.utils.Sequence):
    def __init__(self, df, image_dir, batch_size, img_size):
        self.df = df
        self.image_dir = image_dir
        self.batch_size = batch_size
        self.img_size = img_size
        self.on_epoch_end()

    def __len__(self):
        return int(np.ceil(len(self.df) / float(self.batch_size)))

    def __getitem__(self, idx):
        batch_df = self.df[idx * self.batch_size:(idx + 1) * self.batch_size]
        X, y = self.__data_generation(batch_df)
        return X, y

    def on_epoch_end(self):
        self.indexes = np.arange(len(self.df))
        np.random.shuffle(self.indexes)

    def __data_generation(self, batch_df):
        X_img = []
        X_gender = []
        y = []

        for _, row in batch_df.iterrows():
            # 获取图像数据
            img_name = row['ID'] + '.png'  # 添加扩展名
            img_path = os.path.join(self.image_dir, img_name)
            try:
                img = image.load_img(img_path, color_mode='grayscale', target_size=self.img_size)
            except FileNotFoundError:
                print(f"File not found: {img_path}")
                continue
            img = image.img_to_array(img)

            # Convert grayscale to RGB by repeating the single channel 3 times
            img = np.repeat(img, 3, axis=2)

            img = datagen.standardize(img)
            X_img.append(img)

            # 获取性别数据
            gender = row['Male']
            X_gender.append(gender)

            # 获取骨龄
            boneage = row['BoneAge']
            y.append(boneage)

        X_img = np.array(X_img)
        X_gender = np.array(X_gender)
        y = np.array(y)

        return ([X_img, X_gender], y)


# 创建训练和验证数据生成器
train_generator = CustomDataGenerator(train_boneage_info, images_dir, BATCH_SIZE, (IMG_WIDTH, IMG_HEIGHT))
validation_generator = CustomDataGenerator(val_boneage_info, images_dir, BATCH_SIZE, (IMG_WIDTH, IMG_HEIGHT))

# 构建模型
IMG_CHANNELS = 3
base_model = InceptionV3(weights='imagenet', include_top=False, input_shape=(IMG_WIDTH, IMG_HEIGHT, IMG_CHANNELS))

# 添加性别信息
gender_input = Input(shape=(1,), dtype=tf.int32)

# 将整数值转换为浮点数,以便进行后续处理
gender_float = tf.cast(gender_input, tf.float32)
gender_dense = Dense(32, activation='relu')(gender_float)

# 提取InceptionV3的最后一层
last_layer = base_model.output
flatten = Flatten()(last_layer)

# 拼接性别信息
concat = Concatenate()([flatten, gender_dense])

# 添加额外的全连接层
dense1 = Dense(1000, activation='relu')(concat)
dense2 = Dense(1000, activation='relu')(dense1)

# 最终输出层
output = Dense(1)(dense2)

# 创建模型
model = Model(inputs=[base_model.input, gender_input], outputs=output)

# 编译模型
model.compile(optimizer=Adam(learning_rate=LEARNING_RATE), loss='mean_absolute_error')

# 定义早停和学习率衰减回调
#early_stopping = EarlyStopping(monitor='val_loss', patience=10)
educe_lr = ReduceLROnPlateau(monitor='val_loss', factor=0.2, patience=5, min_lr=0.0001)
early_stopping = EarlyStopping(monitor='val_loss', patience=10, restore_best_weights=True)
# 训练模型
history = model.fit(
    train_generator,
    steps_per_epoch=len(train_generator),
    validation_data=validation_generator,
    validation_steps=len(validation_generator),
    epochs=EPOCHS,
    callbacks=[reduce_lr,early_stopping]
)

# 保存模型
model.save(r'D:\python_code\Bone-Age-Assessment-master\bone_age_model_processed.h5')
相关推荐
运维开发王义杰5 分钟前
Python: 告别 ModuleNotFoundError, 解决 pipx 环境下 sshuttle 缺少 pydivert 依赖的终极指南
开发语言·python
DanCheng-studio32 分钟前
毕设 基于机器视觉的驾驶疲劳检测系统(源码+论文)
python·毕业设计·毕设
carpell34 分钟前
【语义分割专栏】3:Segnet实战篇(附上完整可运行的代码pytorch)
人工智能·python·深度学习·计算机视觉·语义分割
一只小波波呀1 小时前
打卡第48天
python
zstar-_2 小时前
一套个人知识储备库构建方案
python
Amo Xiang2 小时前
《100天精通Python——基础篇 2025 第5天:巩固核心知识,选择题实战演练基础语法》
python·选择题·基础语法
江梦寻2 小时前
MacOS下Homebrew国内镜像加速指南(2025最新国内镜像加速)
开发语言·后端·python·macos·架构·策略模式
霖檬ing2 小时前
Python——MySQL远程控制
开发语言·python·mysql
miniwa2 小时前
Python编程精进:CSV 模块
python
老胖闲聊9 小时前
Python Copilot【代码辅助工具】 简介
开发语言·python·copilot