- import tensorflow as tf
- from tensorflow.keras.layers import Input, Conv2D, MaxPooling2D, Dropout, UpSampling2D, concatenate
-
- # 定义 U-Net 模型
- def unet(input_size=(256, 256, 3)):
- inputs = Input(input_size)
-
- # 编码器部分
- conv1 = Conv2D(64, 3, activation='relu', padding='same', kernel_initializer='he_normal')(inputs)
- conv1 = Conv2D(64, 3, activation='relu', padding='same', kernel_initializer='he_normal')(conv1)
- pool1 = MaxPooling2D(pool_size=(2, 2))(conv1)
-
- conv2 = Conv2D(128, 3, activation='relu', padding='same', kernel_initializer='he_normal')(pool1)
- conv2 = Conv2D(128, 3, activation='relu', padding='same', kernel_initializer='he_normal')(conv2)
- pool2 = MaxPooling2D(pool_size=(2, 2))(conv2)
-
- conv3 = Conv2D(256, 3, activation='relu', padding='same', kernel_initializer='he_normal')(pool2)
- conv3 = Conv2D(256, 3, activation='relu', padding='same', kernel_initializer='he_normal')(conv3)
- pool3 = MaxPooling2D(pool_size=(2, 2))(conv3)
-
- conv4 = Conv2D(512, 3, activation='relu', padding='same', kernel_initializer='he_normal')(pool3)
- conv4 = Conv2D(512, 3, activation='relu', padding='same', kernel_initializer='he_normal')(conv4)
- drop4 = Dropout(0.5)(conv4)
- pool4 = MaxPooling2D(pool_size=(2, 2))(drop4)
-
- # 中间层
- conv5 = Conv2D(1024, 3, activation='relu', padding='same', kernel_initializer='he_normal')(pool4)
- conv5 = Conv2D(1024, 3, activation='relu', padding='same', kernel_initializer='he_normal')(conv5)
- drop5 = Dropout(0.5)(conv5)
-
- # 解码器部分
- up6 = Conv2D(512, 2, activation='relu', padding='same', kernel_initializer='he_normal')(UpSampling2D(size=(2, 2))(drop5))
- merge6 = concatenate([drop4, up6], axis=3)
- conv6 = Conv2D(512, 3, activation='relu', padding='same', kernel_initializer='he_normal')(merge6)
- conv6 = Conv2D(512, 3, activation='relu', padding='same', kernel_initializer='he_normal')(conv6)
-
- up7 = Conv2D(256, 2, activation='relu', padding='same', kernel_initializer='he_normal')(UpSampling2D(size=(2, 2))(conv6))
- merge7 = concatenate([conv3, up7], axis=3)
- conv7 = Conv2D(256, 3, activation='relu', padding='same', kernel_initializer='he_normal')(merge7)
- conv7 = Conv2D(256, 3, activation='relu', padding='same', kernel_initializer='he_normal')(conv7)
-
- up8 = Conv2D(128, 2, activation='relu', padding='same', kernel_initializer='he_normal')(UpSampling2D(size=(2, 2))(conv7))
- merge8 = concatenate([conv2, up8], axis=3)
- conv8 = Conv2D(128, 3, activation='relu', padding='same', kernel_initializer='he_normal')(merge8)
- conv8 = Conv2D(128, 3, activation='relu', padding='same', kernel_initializer='he_normal')(conv8)
-
- up9 = Conv2D(64, 2, activation='relu', padding='same', kernel_initializer='he_normal')(UpSampling2D(size=(2, 2))(conv8))
- merge9 = concatenate([conv1, up9], axis=3)
- conv9 = Conv2D(64, 3, activation='relu', padding='same', kernel_initializer='he_normal')(merge9)
- conv9 = Conv2D(64, 3, activation='relu', padding='same', kernel_initializer='he_normal')(conv9)
-
- outputs = Conv2D(1, 1, activation='sigmoid')(conv9)
-
- model = tf.keras.Model(inputs=inputs, outputs=outputs)
-
- return model
-
- # 创建 U-Net 模型
- model = unet()
- model.summary()
一个简单的 U-Net 模型的 TensorFlow 2.x 代码示例。U-Net 模型通常用于图像分割任务。
需要提前准备好train_images
和train_masks
变量,它们分别包含训练图像和对应的分割掩膜。
- import tensorflow as tf
- import numpy as np
- from tensorflow.keras.layers import Input, Conv2D, MaxPooling2D, Dropout, UpSampling2D, concatenate
- from tensorflow.keras.models import Model
- from tensorflow.keras.optimizers import Adam
- from sklearn.model_selection import train_test_split
-
- # 定义 U-Net 模型
- def unet(input_size=(256, 256, 3)):
- inputs = Input(input_size)
-
- # 编码器部分
- conv1 = Conv2D(64, 3, activation='relu', padding='same', kernel_initializer='he_normal')(inputs)
- conv1 = Conv2D(64, 3, activation='relu', padding='same', kernel_initializer='he_normal')(conv1)
- pool1 = MaxPooling2D(pool_size=(2, 2))(conv1)
-
- conv2 = Conv2D(128, 3, activation='relu', padding='same', kernel_initializer='he_normal')(pool1)
- conv2 = Conv2D(128, 3, activation='relu', padding='same', kernel_initializer='he_normal')(conv2)
- pool2 = MaxPooling2D(pool_size=(2, 2))(conv2)
-
- # ...(更多的编码器层)
-
- # 底层
- conv5 = Conv2D(1024, 3, activation='relu', padding='same', kernel_initializer='he_normal')(pool4)
- conv5 = Conv2D(1024, 3, activation='relu', padding='same', kernel_initializer='he_normal')(conv5)
- drop5 = Dropout(0.5)(conv5)
-
- # 解码器部分
- up6 = UpSampling2D(size=(2, 2))(drop5)
- up6 = Conv2D(512, 2, activation='relu', padding='same', kernel_initializer='he_normal')(up6)
- merge6 = concatenate([drop4, up6], axis=3)
- conv6 = Conv2D(512, 3, activation='relu', padding='same', kernel_initializer='he_normal')(merge6)
- conv6 = Conv2D(512, 3, activation='relu', padding='same', kernel_initializer='he_normal')(conv6)
-
- # ...(更多的解码器层)
-
- # 输出层
- conv10 = Conv2D(1, 1, activation='sigmoid')(conv9)
-
- model = Model(inputs=inputs, outputs=conv10)
- return model
-
- # 准备训练数据和标签
- # 这里假设你已经有了医学图像数据集,以及相应的分割标签
- # 请根据你的数据集的格式来加载和预处理数据
- # 假设训练数据和标签分别存储在 train_images 和 train_masks 中
-
- # 划分训练集和验证集
- X_train, X_val, y_train, y_val = train_test_split(train_images, train_masks, test_size=0.2, random_state=42)
-
- # 创建 U-Net 模型
- model = unet(input_size=(256, 256, 1)) # 修改为你的输入图像尺寸
-
- # 编译模型
- model.compile(optimizer=Adam(lr=1e-4), loss='binary_crossentropy', metrics=['accuracy'])
-
- # 训练模型
- model.fit(X_train, y_train, batch_size=4, epochs=10, validation_data=(X_val, y_val))
-
- # 保存模型
- model.save("unet_medical_segmentation.h5")
上代码中省略了一些编码器和解码器层的详细实现,这些层应该是对称的,并且解码器部分的每一层都应该与编码器部分的相应层进行连接(跳跃连接)。
你需要根据你的具体需求添加更多的编码器和解码器层。
此外,训练数据和标签的加载和预处理步骤需要根据你的数据集格式进行相应的调整。如果你的标签是多分类的,你可能需要将最后一层的激活函数从sigmoid
改为softmax
,并且调整损失函数为categorical_crossentropy
。如果你的图像是单通道的(例如灰度图),则需要确保输入大小的通道数为1。
在加载和预处理医学图像数据时,可以使用 Python 中的图像处理库如 OpenCV 或 Pillow。调整大小和预处理医学图像的示例代码
- import cv2
- import numpy as np
- def load_and_preprocess_image(image_path, target_size=(256, 256)):
- # 读取图像
- image = cv2.imread(image_path)
- # 如果需要,调整图像大小
- if target_size is not None:
- image = cv2.resize(image, target_size)
- # 预处理图像(根据你的需求进行进一步的预处理,如归一化)
- image = image / 255.0 # 归一化到 [0, 1] 范围
- return image
- # 示例用法:
- image_path = "your_image.jpg" # 替换成你的图像文件路径
- target_size = (256, 256) # 替换成你想要的目标大小
- # 加载和预处理图像
- preprocessed_image = load_and_preprocess_image(image_path, target_size)
- # 打印图像的形状(用于验证)
- print("Image shape:", preprocessed_image.shape)
它遍历目录中的图像文件,加载并预处理这些图像,然后将它们转换为 TensorFlow 张量
- import tensorflow as tf
- import os
- import cv2
- import numpy as np
-
- def load_and_preprocess_image(image_path, target_size=(256, 256)):
- # 读取图像
- image = cv2.imread(image_path)
-
- # 如果需要,调整图像大小
- if target_size is not None:
- image = cv2.resize(image, target_size)
-
- # 预处理图像(根据你的需求进行进一步的预处理,如归一化)
- image = image / 255.0 # 归一化到 [0, 1] 范围
-
- return image
-
- def load_and_preprocess_images_in_directory(directory, target_size=(256, 256)):
- images = []
-
- # 遍历目录中的图像文件
- for filename in os.listdir(directory):
- if filename.endswith(".jpg") or filename.endswith(".png"):
- image_path = os.path.join(directory, filename)
- preprocessed_image = load_and_preprocess_image(image_path, target_size)
- images.append(preprocessed_image)
-
- # 将图像列表转换为 TensorFlow 张量
- images = np.array(images)
- images = tf.convert_to_tensor(images, dtype=tf.float32)
-
- return images
-
- # 示例用法:
- image_directory = "your_image_directory" # 替换成包含图像的目录路径
- target_size = (256, 256) # 替换成你想要的目标大小
-
- # 加载和预处理图像
- image_tensor = load_and_preprocess_images_in_directory(image_directory, target_size)
-
- # 打印图像张量的形状(用于验证)
- print("Image tensor shape:", image_tensor.shape)