文章目录

0.环境要求1.加载包和数据集1.1加载包1.2加载数据

2.加载和增强图像Generator3.对训练集做增强用于下面的训练模型3.构建ResUNet模型4.Loss & Compile5.Training6.Testing

0.环境要求

Crack 500数据集下载: https://download.csdn.net/download/QH2107/87423329

创建一个环境,python版本为3.6.13

建一个requirements.txt文件

#新建requirements.txt

absl-py==0.15.0

aiohttp==3.7.4.post0

albumentations==1.3.0

argon2-cffi==20.1.0

astor==0.8.1

async-generator==1.10

async-timeout==3.0.1

attrs==21.4.0

backcall==0.2.0

bleach==4.1.0

blinker==1.4

brotlipy==0.7.0

cachetools==4.2.2

certifi==2021.5.30

cffi==1.14.6

chardet==4.0.0

charset-normalizer==2.0.4

click==8.0.3

colorama==0.4.4

coverage==5.5

cryptography==3.4.7

cycler==0.11.0

Cython==0.29.24

dataclasses==0.8

decorator==5.1.1

defusedxml==0.7.1

entrypoints==0.3

gast==0.2.2

google-auth==2.6.0

google-auth-oauthlib==0.4.4

google-pasta==0.2.0

graphviz==0.19.1

grpcio==1.36.1

h5py==2.10.0

idna==3.3

idna-ssl==1.1.0

imageio==2.15.0

importlib-metadata==4.8.1

ipykernel==5.3.4

ipython==7.16.1

ipython-genutils==0.2.0

ipywidgets==7.6.5

jedi==0.17.0

Jinja2==3.0.3

joblib==1.1.1

jsonschema==3.0.2

jupyter==1.0.0

jupyter-client==7.1.2

jupyter-console==6.4.3

jupyter-contrib-core==0.4.0

jupyter-contrib-nbextensions==0.7.0

jupyter-core==4.8.1

jupyter-highlight-selected-word==0.2.0

jupyter-latex-envs==1.4.6

jupyter-nbextensions-configurator==0.6.1

jupyterlab-pygments==0.1.2

jupyterlab-widgets==1.0.0

Keras==2.3.1

Keras-Applications==1.0.8

Keras-Preprocessing==1.1.2

kiwisolver==1.3.1

lxml==3.8.0

Markdown==3.3.4

MarkupSafe==2.0.1

matplotlib==3.3.4

mistune==0.8.4

mkl-fft==1.3.0

mkl-random==1.1.1

mkl-service==2.3.0

multidict==5.1.0

nb-conda==2.2.1

nb-conda-kernels==2.3.1

nbclient==0.5.3

nbconvert==6.0.7

nbformat==5.1.3

nest-asyncio==1.5.1

networkx==2.5.1

notebook==6.4.3

numpy==1.19.2

oauthlib==3.2.0

olefile==0.46

opencv-python==4.5.5.62

opt-einsum==3.3.0

packaging==21.3

pandas==1.1.5

pandocfilters==1.5.0

parso==0.8.3

pickleshare==0.7.5

Pillow==8.4.0

pip==21.3.1

prometheus-client==0.13.1

prompt-toolkit==3.0.20

protobuf==3.17.2

pyasn1==0.4.8

pyasn1-modules==0.2.8

pycparser==2.21

pydot==1.4.2

pydot-ng==2.0.0

pydotplus==2.0.2

Pygments==2.11.2

PyJWT==2.1.0

pyOpenSSL==21.0.0

pyparsing==3.0.4

pyreadline==2.1

pyrsistent==0.17.3

PySocks==1.7.1

python-dateutil==2.8.2

pytz==2022.7.1

PyWavelets==1.1.1

pywin32==228

pywinpty==0.5.7

PyYAML==6.0

pyzmq==22.2.1

qtconsole==5.2.2

QtPy==2.0.1

qudida==0.0.4

requests==2.27.1

requests-oauthlib==1.3.0

rsa==4.7.2

scikit-image==0.17.2

scikit-learn==0.24.2

scipy==1.5.2

seaborn==0.11.2

Send2Trash==1.8.0

setuptools==58.0.4

six==1.16.0

sklean==0.0.3

tensorboard==2.4.0

tensorboard-plugin-wit==1.6.0

tensorflow==2.1.0

tensorflow-estimator==2.1.0

termcolor==1.1.0

terminado==0.9.4

testpath==0.5.0

tf-unet==0.1.2

threadpoolctl==3.1.0

tifffile==2020.9.3

tornado==6.1

traitlets==4.3.3

typing_extensions==4.1.1

urllib3==1.26.8

wcwidth==0.2.5

webencodings==0.5.1

Werkzeug==0.16.1

wheel==0.37.1

widgetsnbextension==3.5.1

win-inet-pton==1.1.0

wincertstore==0.2

wrapt==1.12.1

yarl==1.6.3

zipp==3.6.0

通过下面命令安全所需要的包

conda install --yes --file requirements.txt

pip install -r requirements.txt

1.加载包和数据集

! nvidia-smi

Mon Feb 6 12:48:07 2023

+-----------------------------------------------------------------------------+

| NVIDIA-SMI 512.78 Driver Version: 512.78 CUDA Version: 11.6 |

|-------------------------------+----------------------+----------------------+

| GPU Name TCC/WDDM | Bus-Id Disp.A | Volatile Uncorr. ECC |

| Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. |

| | | MIG M. |

|===============================+======================+======================|

| 0 NVIDIA GeForce ... WDDM | 00000000:01:00.0 Off | N/A |

| N/A 43C P0 26W / N/A | 0MiB / 6144MiB | 0% Default |

| | | N/A |

+-------------------------------+----------------------+----------------------+

+-----------------------------------------------------------------------------+

| Processes: |

| GPU GI CI PID Type Process name GPU Memory |

| ID ID Usage |

|=============================================================================|

| No running processes found |

+-----------------------------------------------------------------------------+

1.1加载包

import os

import cv2

import shutil

import math

import numpy as np

import seaborn as sns

import matplotlib.pyplot as plt

sns.set()

import tensorflow as tf

from tensorflow import keras

import tensorflow.keras.backend as K

from tensorflow.keras.utils import Sequence

from tensorflow.keras.models import Model

from tensorflow.keras.layers import Input, Conv2D, BatchNormalization, Activation, MaxPooling2D, Conv2DTranspose, Add, concatenate, average, Dropout

from tensorflow.keras.losses import binary_crossentropy

from tensorflow.keras.callbacks import EarlyStopping, ReduceLROnPlateau

from sklearn.metrics import classification_report, roc_auc_score, accuracy_score

from albumentations import Compose, OneOf, Flip, Rotate, RandomContrast, RandomGamma, RandomBrightness, ElasticTransform, GridDistortion, OpticalDistortion, RGBShift, CLAHE

from tensorflow.keras.losses import binary_crossentropy

from tensorflow.keras.callbacks import EarlyStopping, ReduceLROnPlateau

from skimage.transform import resize

from sklearn.metrics import classification_report

1.2加载数据

#数据集的文件夹路径

train_image_dir = r'E:\dataset\CRACK500\train\image'

train_mask_dir = r'E:\dataset\CRACK500\train\mask'

valid_image_dir = r'E:\dataset\CRACK500\validation\image'

valid_mask_dir =r'E:\dataset\CRACK500\validation\mask'

test_image_dir = r'E:\dataset\CRACK500\test\image'

test_mask_dir = r'E:\dataset\CRACK500\test\mask'

#数据集的文件路径(image对应mask)

# 测试集

test_image_paths = sorted([os.path.join(test_image_dir, fname) for fname in os.listdir(test_image_dir) if fname.endswith(".png") and not fname.startswith(".")])

test_mask_paths = sorted([os.path.join(test_mask_dir, fname) for fname in os.listdir(test_mask_dir) if fname.endswith(".png") and not fname.startswith(".")])

print("Number of testing images : ", len(test_image_paths))

print("Number of testing masks : ", len(test_mask_paths))

# 训练集

train_image_files = sorted([os.path.join(train_image_dir, fname) for fname in os.listdir(train_image_dir) if fname.endswith(".png") and not fname.startswith(".")])

train_mask_files = sorted([os.path.join(train_mask_dir, fname) for fname in os.listdir(train_mask_dir) if fname.endswith(".png") and not fname.startswith(".")])

print("Number of training images : ", len(train_image_files))

print("Number of training masks : ", len(train_mask_files))

#验证集

valid_image_files = sorted([os.path.join(valid_image_dir, fname) for fname in os.listdir(valid_image_dir) if fname.endswith(".png") and not fname.startswith(".")])

valid_mask_files = sorted([os.path.join(valid_mask_dir, fname) for fname in os.listdir(valid_mask_dir) if fname.endswith(".png") and not fname.startswith(".")])

print("Number of validing images : ", len(valid_image_files))

print("Number of validing masks : ", len(valid_mask_files))

#结果

Number of testing images : 1124

Number of testing masks : 1124

Number of training images : 1896

Number of training masks : 1896

Number of validing images : 348

Number of validing masks : 348

batch_size = 4 #批大小,显存不够可以再小一点

img_dim=(320, 640) #图像大小

2.加载和增强图像Generator

class Generator(Sequence):

def __init__(self, x_set, y_set, batch_size=5, img_dim=(128, 128), augment=False):

self.x = x_set

self.y = y_set

self.batch_size = batch_size

self.img_dim = img_dim

self.augment = augment

def __len__(self):

return math.ceil(len(self.x) / self.batch_size)

augmentations = Compose(

[

Flip(p=0.7),

Rotate(p=0.7),

OneOf([

RandomContrast(),

RandomGamma(),

RandomBrightness()

], p=0.3),

OneOf([

ElasticTransform(alpha=120, sigma=120 * 0.05, alpha_affine=120 * 0.03),

GridDistortion(),

OpticalDistortion(distort_limit=2, shift_limit=0.5)

], p=0.3),

])

def __getitem__(self, idx):

batch_x = self.x[idx * self.batch_size:(idx + 1) * self.batch_size]

batch_y = self.y[idx * self.batch_size:(idx + 1) * self.batch_size]

batch_x = np.array([cv2.resize(cv2.cvtColor(cv2.imread(file_name, -1), cv2.COLOR_BGR2RGB), (self.img_dim[1], self.img_dim[0])) for file_name in batch_x])

batch_y = np.array([(cv2.resize(cv2.imread(file_name, -1), (self.img_dim[1], self.img_dim[0]))>0).astype(np.uint8) for file_name in batch_y])

if self.augment is True:

aug = [self.augmentations(image=i, mask=j) for i, j in zip(batch_x, batch_y)]

batch_x = np.array([i['image'] for i in aug])

batch_y = np.array([j['mask'] for j in aug])

batch_y = np.expand_dims(batch_y, -1)

return batch_x/255, batch_y/1

# 对测试集处理

test1_generator=Generator(test_image_paths,test_mask_paths,batch_size,img_dim,False)

# 生成的样本 (未增强)

for i, j in test1_generator:

break

fig, axes = plt.subplots(1, 4, figsize=(13,2.5))

fig.suptitle('Original Images (test)', fontsize=15)

axes = axes.flatten()

for img, ax in zip(i[:4], axes[:4]):

ax.imshow(img)

ax.axis('off')

plt.tight_layout()

plt.show()

fig, axes = plt.subplots(1, 4, figsize=(13,3))

fig.suptitle('Original Masks (test)', fontsize=15)

axes = axes.flatten()

for img, ax in zip(j[:4], axes[:4]):

ax.imshow(np.squeeze(img, -1), cmap='gray')

ax.axis('off')

plt.tight_layout()

plt.show()

# 对训练集和验证集做同样的处理

train_generator = Generator(train_image_files, train_mask_files,batch_size,img_dim,False)

validation_generator = Generator(valid_image_files, valid_mask_files,batch_size,img_dim,False)

for i, j in train_generator:

break

print(i.shape)

print(j.shape)

(4, 320, 640, 3)

(4, 320, 640, 1)

for i, j in validation_generator:

break

print(i.shape)

print(j.shape)

(4, 320, 640, 3)

(4, 320, 640, 1)

# 生成的样本(未增强)

for i, j in train_generator:

break

fig, axes = plt.subplots(1, 4, figsize=(13,2.5))

fig.suptitle('Original Images (train)', fontsize=15)

axes = axes.flatten()

for img, ax in zip(i[:4], axes[:4]):

ax.imshow(img)

ax.axis('off')

plt.tight_layout()

plt.show()

fig, axes = plt.subplots(1, 4, figsize=(13,2.5))

fig.suptitle('Original Masks (train)', fontsize=15)

axes = axes.flatten()

for img, ax in zip(j[:4], axes[:4]):

ax.imshow(np.squeeze(img, -1), cmap='gray')

ax.axis('off')

plt.tight_layout()

plt.show()

# 生成的样本 (未增强)

for i, j in validation_generator:

break

fig, axes = plt.subplots(1, 4, figsize=(13,2.5))

fig.suptitle('Original Images (validation)', fontsize=15)

axes = axes.flatten()

for img, ax in zip(i[:4], axes[:4]):

ax.imshow(img)

ax.axis('off')

plt.tight_layout()

plt.show()

fig, axes = plt.subplots(1, 4, figsize=(13,2.5))

fig.suptitle('Original Masks (validation)', fontsize=15)

axes = axes.flatten()

for img, ax in zip(j[:4], axes[:4]):

ax.imshow(np.squeeze(img, -1), cmap='gray')

ax.axis('off')

plt.tight_layout()

plt.show()

3.对训练集做增强用于下面的训练模型

tg = Generator(train_image_files, train_mask_files, batch_size, img_dim, augment = True) #训练集

vg = Generator(valid_image_files, valid_mask_files, batch_size, img_dim, augment = False)#验证集

for i, j in tg:

break

print(i.shape)

print(j.shape)

#结果

(4, 320, 640, 3)

(4, 320, 640, 1)

for i, j in vg:

break

print(i.shape)

print(j.shape)

#结果

(4, 320, 640, 3)

(4, 320, 640, 1)

# Augmented train

for i, j in tg:

break

fig, axes = plt.subplots(1, 4, figsize=(13,2.5))

fig.suptitle('Augmented Images', fontsize=15)

axes = axes.flatten()

for img, ax in zip(i[:4], axes[:4]):

ax.imshow(img)

ax.axis('off')

plt.tight_layout()

plt.show()

fig, axes = plt.subplots(1, 4, figsize=(13,2.5))

fig.suptitle('Augmented Masks', fontsize=15)

axes = axes.flatten()

for img, ax in zip(j[:4], axes[:4]):

ax.imshow(np.squeeze(img, -1), cmap='gray')

ax.axis('off')

plt.tight_layout()

plt.show()

3.构建ResUNet模型

import numpy as np

from tensorflow.keras.backend import int_shape

from tensorflow.keras.models import Model

from tensorflow.keras.layers import Conv2D, MaxPooling2D, UpSampling2D, Add, BatchNormalization, Input, Activation, Concatenate

from keras.regularizers import l2

# BatchNormalization and Activation

def BN_Act(x, act = True):

x = BatchNormalization()(x)

if act == True:

x = Activation("relu")(x)

return x

#conv2d block

def conv2d_block(x, filters, kernel_size = (3, 3), padding = "same", strides = 1):

conv = BN_Act(x)

conv = Conv2D(filters, kernel_size, padding = padding, strides = strides)(conv)

return conv

#Fixed layer.

def stem(x, filters, kernel_size=(3, 3), padding="same", strides=1):

conv = Conv2D(filters, kernel_size, padding = padding, strides = strides)(x)

conv = conv2d_block(conv, filters, kernel_size = kernel_size, padding = padding, strides = strides)

#skip

shortcut = Conv2D(filters, kernel_size = (1, 1), padding = padding, strides = strides)(x)

shortcut = BN_Act(shortcut, act = False) # No activation in skip connection

output = Add()([conv, shortcut])

return output

# Residual Block

def residual_block(x, filters, kernel_size = (3, 3), padding = "same", strides = 1):

res = conv2d_block(x, filters, kernel_size = kernel_size, padding = padding, strides = strides)

res = conv2d_block(res, filters, kernel_size = kernel_size, padding = padding, strides = 1)

shortcut = Conv2D(filters, kernel_size = (1, 1), padding = padding, strides = strides)(x)

shortcut = BN_Act(shortcut, act = False) # No activation in skip connection

output = Add()([shortcut, res])

return output

# Upsampling Concatenation block

def upsample_concat_block(x, xskip):

u = UpSampling2D((2, 2))(x)

c = Concatenate()([u, xskip])

return c

# MODEL

def ResUNet():

f = [16, 32, 64, 128, 256]

inputs = Input((img_dim[0], img_dim[1], 3))

## Encoder/downsampling/contracting path

e0 = inputs

e1 = stem(e0, f[0])

e2 = residual_block(e1, f[1], strides = 2)

e3 = residual_block(e2, f[2], strides = 2)

e4 = residual_block(e3, f[3], strides = 2)

e5 = residual_block(e4, f[4], strides = 2)

## Bridge/Bottleneck

b0 = conv2d_block(e5, f[4], strides = 1)

b1 = conv2d_block(b0, f[4], strides = 1)

## Decoder/upsampling/expansive path

u1 = upsample_concat_block(b1, e4)

d1 = residual_block(u1, f[4])

u2 = upsample_concat_block(d1, e3)

d2 = residual_block(u2, f[3])

u3 = upsample_concat_block(d2, e2)

d3 = residual_block(u3, f[2])

u4 = upsample_concat_block(d3, e1)

d4 = residual_block(u4, f[1])

outputs = Conv2D(1, (1, 1), padding = "same", activation = "sigmoid")(d4)

model = Model(inputs, outputs)

return model

K.clear_session()

model = ResUNet()

model.summary()

#结果

Model: "model"

__________________________________________________________________________________________________

Layer (type) Output Shape Param # Connected to

==================================================================================================

input_1 (InputLayer) [(None, 320, 640, 3) 0

__________________________________________________________________________________________________

conv2d (Conv2D) (None, 320, 640, 16) 448 input_1[0][0]

__________________________________________________________________________________________________

batch_normalization (BatchNorma (None, 320, 640, 16) 64 conv2d[0][0]

__________________________________________________________________________________________________

activation (Activation) (None, 320, 640, 16) 0 batch_normalization[0][0]

__________________________________________________________________________________________________

conv2d_2 (Conv2D) (None, 320, 640, 16) 64 input_1[0][0]

__________________________________________________________________________________________________

conv2d_1 (Conv2D) (None, 320, 640, 16) 2320 activation[0][0]

__________________________________________________________________________________________________

batch_normalization_1 (BatchNor (None, 320, 640, 16) 64 conv2d_2[0][0]

__________________________________________________________________________________________________

add (Add) (None, 320, 640, 16) 0 conv2d_1[0][0]

batch_normalization_1[0][0]

__________________________________________________________________________________________________

batch_normalization_2 (BatchNor (None, 320, 640, 16) 64 add[0][0]

__________________________________________________________________________________________________

activation_1 (Activation) (None, 320, 640, 16) 0 batch_normalization_2[0][0]

__________________________________________________________________________________________________

conv2d_3 (Conv2D) (None, 160, 320, 32) 4640 activation_1[0][0]

__________________________________________________________________________________________________

batch_normalization_3 (BatchNor (None, 160, 320, 32) 128 conv2d_3[0][0]

__________________________________________________________________________________________________

conv2d_5 (Conv2D) (None, 160, 320, 32) 544 add[0][0]

__________________________________________________________________________________________________

activation_2 (Activation) (None, 160, 320, 32) 0 batch_normalization_3[0][0]

__________________________________________________________________________________________________

batch_normalization_4 (BatchNor (None, 160, 320, 32) 128 conv2d_5[0][0]

__________________________________________________________________________________________________

conv2d_4 (Conv2D) (None, 160, 320, 32) 9248 activation_2[0][0]

__________________________________________________________________________________________________

add_1 (Add) (None, 160, 320, 32) 0 batch_normalization_4[0][0]

conv2d_4[0][0]

__________________________________________________________________________________________________

batch_normalization_5 (BatchNor (None, 160, 320, 32) 128 add_1[0][0]

__________________________________________________________________________________________________

activation_3 (Activation) (None, 160, 320, 32) 0 batch_normalization_5[0][0]

__________________________________________________________________________________________________

conv2d_6 (Conv2D) (None, 80, 160, 64) 18496 activation_3[0][0]

__________________________________________________________________________________________________

batch_normalization_6 (BatchNor (None, 80, 160, 64) 256 conv2d_6[0][0]

__________________________________________________________________________________________________

conv2d_8 (Conv2D) (None, 80, 160, 64) 2112 add_1[0][0]

__________________________________________________________________________________________________

activation_4 (Activation) (None, 80, 160, 64) 0 batch_normalization_6[0][0]

__________________________________________________________________________________________________

batch_normalization_7 (BatchNor (None, 80, 160, 64) 256 conv2d_8[0][0]

__________________________________________________________________________________________________

conv2d_7 (Conv2D) (None, 80, 160, 64) 36928 activation_4[0][0]

__________________________________________________________________________________________________

add_2 (Add) (None, 80, 160, 64) 0 batch_normalization_7[0][0]

conv2d_7[0][0]

__________________________________________________________________________________________________

batch_normalization_8 (BatchNor (None, 80, 160, 64) 256 add_2[0][0]

__________________________________________________________________________________________________

activation_5 (Activation) (None, 80, 160, 64) 0 batch_normalization_8[0][0]

__________________________________________________________________________________________________

conv2d_9 (Conv2D) (None, 40, 80, 128) 73856 activation_5[0][0]

__________________________________________________________________________________________________

batch_normalization_9 (BatchNor (None, 40, 80, 128) 512 conv2d_9[0][0]

__________________________________________________________________________________________________

conv2d_11 (Conv2D) (None, 40, 80, 128) 8320 add_2[0][0]

__________________________________________________________________________________________________

activation_6 (Activation) (None, 40, 80, 128) 0 batch_normalization_9[0][0]

__________________________________________________________________________________________________

batch_normalization_10 (BatchNo (None, 40, 80, 128) 512 conv2d_11[0][0]

__________________________________________________________________________________________________

conv2d_10 (Conv2D) (None, 40, 80, 128) 147584 activation_6[0][0]

__________________________________________________________________________________________________

add_3 (Add) (None, 40, 80, 128) 0 batch_normalization_10[0][0]

conv2d_10[0][0]

__________________________________________________________________________________________________

batch_normalization_11 (BatchNo (None, 40, 80, 128) 512 add_3[0][0]

__________________________________________________________________________________________________

activation_7 (Activation) (None, 40, 80, 128) 0 batch_normalization_11[0][0]

__________________________________________________________________________________________________

conv2d_12 (Conv2D) (None, 20, 40, 256) 295168 activation_7[0][0]

__________________________________________________________________________________________________

batch_normalization_12 (BatchNo (None, 20, 40, 256) 1024 conv2d_12[0][0]

__________________________________________________________________________________________________

conv2d_14 (Conv2D) (None, 20, 40, 256) 33024 add_3[0][0]

__________________________________________________________________________________________________

activation_8 (Activation) (None, 20, 40, 256) 0 batch_normalization_12[0][0]

__________________________________________________________________________________________________

batch_normalization_13 (BatchNo (None, 20, 40, 256) 1024 conv2d_14[0][0]

__________________________________________________________________________________________________

conv2d_13 (Conv2D) (None, 20, 40, 256) 590080 activation_8[0][0]

__________________________________________________________________________________________________

add_4 (Add) (None, 20, 40, 256) 0 batch_normalization_13[0][0]

conv2d_13[0][0]

__________________________________________________________________________________________________

batch_normalization_14 (BatchNo (None, 20, 40, 256) 1024 add_4[0][0]

__________________________________________________________________________________________________

activation_9 (Activation) (None, 20, 40, 256) 0 batch_normalization_14[0][0]

__________________________________________________________________________________________________

conv2d_15 (Conv2D) (None, 20, 40, 256) 590080 activation_9[0][0]

__________________________________________________________________________________________________

batch_normalization_15 (BatchNo (None, 20, 40, 256) 1024 conv2d_15[0][0]

__________________________________________________________________________________________________

activation_10 (Activation) (None, 20, 40, 256) 0 batch_normalization_15[0][0]

__________________________________________________________________________________________________

conv2d_16 (Conv2D) (None, 20, 40, 256) 590080 activation_10[0][0]

__________________________________________________________________________________________________

up_sampling2d (UpSampling2D) (None, 40, 80, 256) 0 conv2d_16[0][0]

__________________________________________________________________________________________________

concatenate (Concatenate) (None, 40, 80, 384) 0 up_sampling2d[0][0]

add_3[0][0]

__________________________________________________________________________________________________

batch_normalization_16 (BatchNo (None, 40, 80, 384) 1536 concatenate[0][0]

__________________________________________________________________________________________________

activation_11 (Activation) (None, 40, 80, 384) 0 batch_normalization_16[0][0]

__________________________________________________________________________________________________

conv2d_17 (Conv2D) (None, 40, 80, 256) 884992 activation_11[0][0]

__________________________________________________________________________________________________

batch_normalization_17 (BatchNo (None, 40, 80, 256) 1024 conv2d_17[0][0]

__________________________________________________________________________________________________

conv2d_19 (Conv2D) (None, 40, 80, 256) 98560 concatenate[0][0]

__________________________________________________________________________________________________

activation_12 (Activation) (None, 40, 80, 256) 0 batch_normalization_17[0][0]

__________________________________________________________________________________________________

batch_normalization_18 (BatchNo (None, 40, 80, 256) 1024 conv2d_19[0][0]

__________________________________________________________________________________________________

conv2d_18 (Conv2D) (None, 40, 80, 256) 590080 activation_12[0][0]

__________________________________________________________________________________________________

add_5 (Add) (None, 40, 80, 256) 0 batch_normalization_18[0][0]

conv2d_18[0][0]

__________________________________________________________________________________________________

up_sampling2d_1 (UpSampling2D) (None, 80, 160, 256) 0 add_5[0][0]

__________________________________________________________________________________________________

concatenate_1 (Concatenate) (None, 80, 160, 320) 0 up_sampling2d_1[0][0]

add_2[0][0]

__________________________________________________________________________________________________

batch_normalization_19 (BatchNo (None, 80, 160, 320) 1280 concatenate_1[0][0]

__________________________________________________________________________________________________

activation_13 (Activation) (None, 80, 160, 320) 0 batch_normalization_19[0][0]

__________________________________________________________________________________________________

conv2d_20 (Conv2D) (None, 80, 160, 128) 368768 activation_13[0][0]

__________________________________________________________________________________________________

batch_normalization_20 (BatchNo (None, 80, 160, 128) 512 conv2d_20[0][0]

__________________________________________________________________________________________________

conv2d_22 (Conv2D) (None, 80, 160, 128) 41088 concatenate_1[0][0]

__________________________________________________________________________________________________

activation_14 (Activation) (None, 80, 160, 128) 0 batch_normalization_20[0][0]

__________________________________________________________________________________________________

batch_normalization_21 (BatchNo (None, 80, 160, 128) 512 conv2d_22[0][0]

__________________________________________________________________________________________________

conv2d_21 (Conv2D) (None, 80, 160, 128) 147584 activation_14[0][0]

__________________________________________________________________________________________________

add_6 (Add) (None, 80, 160, 128) 0 batch_normalization_21[0][0]

conv2d_21[0][0]

__________________________________________________________________________________________________

up_sampling2d_2 (UpSampling2D) (None, 160, 320, 128 0 add_6[0][0]

__________________________________________________________________________________________________

concatenate_2 (Concatenate) (None, 160, 320, 160 0 up_sampling2d_2[0][0]

add_1[0][0]

__________________________________________________________________________________________________

batch_normalization_22 (BatchNo (None, 160, 320, 160 640 concatenate_2[0][0]

__________________________________________________________________________________________________

activation_15 (Activation) (None, 160, 320, 160 0 batch_normalization_22[0][0]

__________________________________________________________________________________________________

conv2d_23 (Conv2D) (None, 160, 320, 64) 92224 activation_15[0][0]

__________________________________________________________________________________________________

batch_normalization_23 (BatchNo (None, 160, 320, 64) 256 conv2d_23[0][0]

__________________________________________________________________________________________________

conv2d_25 (Conv2D) (None, 160, 320, 64) 10304 concatenate_2[0][0]

__________________________________________________________________________________________________

activation_16 (Activation) (None, 160, 320, 64) 0 batch_normalization_23[0][0]

__________________________________________________________________________________________________

batch_normalization_24 (BatchNo (None, 160, 320, 64) 256 conv2d_25[0][0]

__________________________________________________________________________________________________

conv2d_24 (Conv2D) (None, 160, 320, 64) 36928 activation_16[0][0]

__________________________________________________________________________________________________

add_7 (Add) (None, 160, 320, 64) 0 batch_normalization_24[0][0]

conv2d_24[0][0]

__________________________________________________________________________________________________

up_sampling2d_3 (UpSampling2D) (None, 320, 640, 64) 0 add_7[0][0]

__________________________________________________________________________________________________

concatenate_3 (Concatenate) (None, 320, 640, 80) 0 up_sampling2d_3[0][0]

add[0][0]

__________________________________________________________________________________________________

batch_normalization_25 (BatchNo (None, 320, 640, 80) 320 concatenate_3[0][0]

__________________________________________________________________________________________________

activation_17 (Activation) (None, 320, 640, 80) 0 batch_normalization_25[0][0]

__________________________________________________________________________________________________

conv2d_26 (Conv2D) (None, 320, 640, 32) 23072 activation_17[0][0]

__________________________________________________________________________________________________

batch_normalization_26 (BatchNo (None, 320, 640, 32) 128 conv2d_26[0][0]

__________________________________________________________________________________________________

conv2d_28 (Conv2D) (None, 320, 640, 32) 2592 concatenate_3[0][0]

__________________________________________________________________________________________________

activation_18 (Activation) (None, 320, 640, 32) 0 batch_normalization_26[0][0]

__________________________________________________________________________________________________

batch_normalization_27 (BatchNo (None, 320, 640, 32) 128 conv2d_28[0][0]

__________________________________________________________________________________________________

conv2d_27 (Conv2D) (None, 320, 640, 32) 9248 activation_18[0][0]

__________________________________________________________________________________________________

add_8 (Add) (None, 320, 640, 32) 0 batch_normalization_27[0][0]

conv2d_27[0][0]

__________________________________________________________________________________________________

conv2d_29 (Conv2D) (None, 320, 640, 1) 33 add_8[0][0]

==================================================================================================

Total params: 4,723,057

Trainable params: 4,715,761

Non-trainable params: 7,296

__________________________________________________________________________________________________

4.Loss & Compile

smooth = 1.

def dice_coef(y_true, y_pred):

y_true_f = K.flatten(y_true)

y_pred_f = K.flatten(y_pred)

intersection = tf.reduce_sum(y_true_f * y_pred_f)

return (2. * intersection + smooth) / (tf.reduce_sum(y_true_f) + tf.reduce_sum(y_pred_f) + smooth)

def dice_coef_loss(y_true, y_pred):

return 1.0 - dice_coef(y_true, y_pred)

def IOU(y_true, y_pred):

y_true = K.flatten(y_true)

y_pred = K.flatten(y_pred)

thresh = 0.5

y_true = K.cast(K.greater_equal(y_true, thresh), 'float32')

y_pred = K.cast(K.greater_equal(y_pred, thresh), 'float32')

union = K.sum(K.maximum(y_true, y_pred)) + K.epsilon()

intersection = K.sum(K.minimum(y_true, y_pred)) + K.epsilon()

iou = intersection/union

return iou

def lr_schedule(epoch):

lr =0.0035

if epoch >150:

lr *=2**-1

elif epoch >80:

lr *=2**(-1)

elif epoch >50:

lr *=2**(-1)

elif epoch >30:

lr *=2**(-1)

print('Learning rate: ', lr)

return lr

from tensorflow.keras.callbacks import ModelCheckpoint

from tensorflow.keras.callbacks import LearningRateScheduler

from keras.optimizers import SGD

import time

start_time = time.time()

# Prepare callbacks for model saving and for learning rate adjustment.

lr_scheduler = LearningRateScheduler(lr_schedule)

lr_reducer = ReduceLROnPlateau(factor=np.sqrt(0.1),

cooldown=0,

patience=5,

min_lr=0.5e-6)

callbacks = [lr_reducer, lr_scheduler]

import tensorflow as tf

optimiser=tf.keras.optimizers.Adam(

learning_rate=lr_schedule(0),

beta_1=0.9,

beta_2=0.999,

epsilon=1e-07,

amsgrad=True,

name="Adam"

)

model.compile(optimizer =optimiser , loss = dice_coef_loss, metrics = ['accuracy', IOU, dice_coef])

#结果

Learning rate: 0.0035

5.Training

train_steps = len(train_image_files)//batch_size

valid_steps = len(valid_image_files)//batch_size

history = model.fit(

tg, #基于上面的训练集

steps_per_epoch=train_steps,

initial_epoch = 0,

epochs=3, #这里只设为3个

validation_data = vg, #基于上面的验证集

validation_steps = valid_steps,callbacks=callbacks)

WARNING:tensorflow:sample_weight modes were coerced from

...

to

['...']

WARNING:tensorflow:sample_weight modes were coerced from

...

to

['...']

Train for 474 steps, validate for 87 steps

Learning rate: 0.0035

Epoch 1/3

474/474 [==============================] - 10471s 22s/step - loss: 0.4093 - accuracy: 0.9513 - IOU: 0.4435 - dice_coef: 0.5907 - val_loss: 0.4153 - val_accuracy: 0.9350 - val_IOU: 0.4442 - val_dice_coef: 0.5847

Learning rate: 0.0035

Epoch 2/3

474/474 [==============================] - 5823s 12s/step - loss: 0.3736 - accuracy: 0.9561 - IOU: 0.4787 - dice_coef: 0.6264 - val_loss: 0.4357 - val_accuracy: 0.8781 - val_IOU: 0.4241 - val_dice_coef: 0.5643

Learning rate: 0.0035

Epoch 3/3

474/474 [==============================] - 6416s 14s/step - loss: 0.3337 - accuracy: 0.9618 - IOU: 0.5186 - dice_coef: 0.6663 - val_loss: 0.4244 - val_accuracy: 0.9004 - val_IOU: 0.4297 - val_dice_coef: 0.5756

train_loss = history.history['loss']

valid_loss = history.history['val_loss']

train_acc = history.history['accuracy']

valid_acc = history.history['val_accuracy']

fig, axes = plt.subplots(1, 2, figsize=(13,4))

axes = axes.flatten()

axes[0].plot(train_acc, label='training')

axes[0].plot(valid_acc, label='validation')

axes[0].set_title('Accuracy Curve')

axes[0].set_xlabel('epochs')

axes[0].set_ylabel('accuracy')

axes[0].legend()

axes[1].plot(train_loss, label='training')

axes[1].plot(valid_loss, label='validation')

axes[1].set_title('Loss Curve')

axes[1].set_xlabel('epochs')

axes[1].set_ylabel('loss')

axes[1].legend()

plt.show()

train_dice = history.history['dice_coef']

valid_dice = history.history['val_dice_coef']

train_IOU = history.history['IOU']

valid_IOU = history.history['val_IOU']

fig, axes = plt.subplots(1, 2, figsize=(20,7))

axes = axes.flatten()

axes[0].plot(train_IOU, label='training')

axes[0].plot(valid_IOU, label='validation')

axes[0].set_title('IOU Curve [Adam lr : 0.0001]')

axes[0].set_xlabel('epochs')

axes[0].set_ylabel('IOU')

axes[0].legend()

axes[1].plot(train_dice, label='training')

axes[1].plot(valid_dice, label='validation')

axes[1].set_title('Dice coefficient Curve [Adam lr : 0.0001]')

axes[1].set_xlabel('epochs')

axes[1].set_ylabel('dice_coef')

axes[1].legend()

plt.show()

6.Testing

test_generator = Generator(valid_image_files, valid_mask_files, 396, img_dim)

for x_test, y_test in test_generator:

break

y_pred = model.predict(x_test)

yy_true = (y_test>0.5).flatten()

yy_pred = (y_pred>0.5).flatten()

report = classification_report(yy_true, yy_pred, output_dict=True)

Accuracy = accuracy_score(yy_true, yy_pred)

Precision = report['True']['precision']

Recall = report['True']['recall']

F1_score = report['True']['f1-score']

Sensitivity = Recall

Specificity = report['False']['recall']

AUC = roc_auc_score(y_test.flatten(), y_pred.flatten())

IOU = (Precision*Recall)/(Precision+Recall-Precision*Recall)

print("Accuracy: {0:.4f}\n".format(Accuracy))

print("Precision: {0:.4f}\n".format(Precision))

print("Recall: {0:.4f}\n".format(Recall))

print("F1-Score: {0:.4f}\n".format(F1_score))

print("Sensitivity: {0:.4f}\n".format(Sensitivity))

print("Specificity: {0:.4f}\n".format(Specificity))

print("AUC: {0:.4f}\n".format(AUC))

print("IOU: {0:.4f}\n".format(IOU))

print('-'*50,'\n')

print(classification_report(yy_true, yy_pred))

#结果

Accuracy: 0.9004

Precision: 0.3555

Recall: 0.8970

F1-Score: 0.5092

Sensitivity: 0.8970

Specificity: 0.9006

AUC: 0.9202

IOU: 0.3415

--------------------------------------------------

precision recall f1-score support

False 0.99 0.90 0.94 67167304

True 0.36 0.90 0.51 4103096

accuracy 0.90 71270400

macro avg 0.67 0.90 0.73 71270400

weighted avg 0.96 0.90 0.92 71270400

for i, j in test1_generator:

break

print(i.shape)

print(j.shape)

#结果

(4, 320, 640, 3)

(4, 320, 640, 1)

ttg = Generator(test_image_paths,test_mask_paths, batch_size, img_dim, augment = False)

for i, j in ttg:

break

print(i.shape)

print(j.shape)

#结果

(4, 320, 640, 3)

(4, 320, 640, 1)

test_generator1 = Generator(test_image_paths,test_mask_paths,1124, img_dim)

for x_test, y_test in test_generator:

break

y_pred = model.predict(x_test)

yy_true = (y_test>0.5).flatten()

yy_pred = (y_pred>0.5).flatten()

report = classification_report(yy_true, yy_pred, output_dict=True)

Accuracy = accuracy_score(yy_true, yy_pred)

Precision = report['True']['precision']

Recall = report['True']['recall']

F1_score = report['True']['f1-score']

Sensitivity = Recall

Specificity = report['False']['recall']

AUC = roc_auc_score(y_test.flatten(), y_pred.flatten())

IOU = (Precision*Recall)/(Precision+Recall-Precision*Recall)

print("Accuracy: {0:.4f}\n".format(Accuracy))

print("Precision: {0:.4f}\n".format(Precision))

print("Recall: {0:.4f}\n".format(Recall))

print("F1-Score: {0:.4f}\n".format(F1_score))

print("Sensitivity: {0:.4f}\n".format(Sensitivity))

print("Specificity: {0:.4f}\n".format(Specificity))

print("AUC: {0:.4f}\n".format(AUC))

print("IOU: {0:.4f}\n".format(IOU))

print('-'*50,'\n')

print(classification_report(yy_true, yy_pred))

#结果

Accuracy: 0.9004

Precision: 0.3555

Recall: 0.8970

F1-Score: 0.5092

Sensitivity: 0.8970

Specificity: 0.9006

AUC: 0.9202

IOU: 0.3415

--------------------------------------------------

precision recall f1-score support

False 0.99 0.90 0.94 67167304

True 0.36 0.90 0.51 4103096

accuracy 0.90 71270400

macro avg 0.67 0.90 0.73 71270400

weighted avg 0.96 0.90 0.92 71270400

参考资料:https://github.com/Subham2901/Concrete_Crack_Segmentation 欢迎关注公众号【智能建造小硕】(分享计算机编程、人工智能、智能建造、日常学习、科研和写作经验等,欢迎大家关注交流。)

参考阅读

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: