├── loss.PNG ├── loss2.PNG ├── 分割结果.png ├── tnscui2.png ├── leadboard.png ├── Vnet2d ├── __init__.py ├── util.py ├── layer.py └── vnet_seg_classify_model.py ├── Resnet2d ├── __init__.py ├── classify_metrics.py ├── layer.py └── model_resNet2d.py ├── TNSCUI2020 ├── Vnet2d │ ├── __init__.py │ ├── util.py │ ├── layer.py │ └── vnet_model.py ├── Resnet2d │ ├── __init__.py │ ├── log │ │ ├── events.out.tfevents.1590841179.WANGCHEN │ │ └── events.out.tfevents.1590844439.WANGCHEN │ ├── classify_metrics.py │ ├── layer.py │ └── model_resNet2d.py ├── dataprocess │ ├── Augmentation │ │ ├── __init__.py │ │ ├── __pycache__ │ │ │ ├── __init__.cpython-35.pyc │ │ │ ├── ImageAugmentation.cpython-35.pyc │ │ │ └── images_masks_transform.cpython-35.pyc │ │ ├── ImageAugmentation.py │ │ └── images_masks_transform.py │ ├── augtest.py │ ├── data2dprepare.py │ ├── utils.py │ └── subset.py ├── vnet2d_train.py ├── resnet2d_train.py ├── resnet2d_predict.py └── vnet2d_predict.py ├── vnet2d_seg_classify_train.py ├── resnet2d_train.py ├── resnet2d_inference.py ├── README.md ├── vnet2d_train.py ├── vnet2d_seg_classify_inference.py └── vnet2d_inference.py /loss.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/junqiangchen/TN-SCUI2020-Challenge/HEAD/loss.PNG -------------------------------------------------------------------------------- /loss2.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/junqiangchen/TN-SCUI2020-Challenge/HEAD/loss2.PNG -------------------------------------------------------------------------------- /分割结果.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/junqiangchen/TN-SCUI2020-Challenge/HEAD/分割结果.png -------------------------------------------------------------------------------- /tnscui2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/junqiangchen/TN-SCUI2020-Challenge/HEAD/tnscui2.png -------------------------------------------------------------------------------- /leadboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/junqiangchen/TN-SCUI2020-Challenge/HEAD/leadboard.png -------------------------------------------------------------------------------- /Vnet2d/__init__.py: -------------------------------------------------------------------------------- 1 | __author__ = 'junqiang chen' 2 | __version__ = '1.0.0' 3 | __time__ = '2020.5.28' 4 | -------------------------------------------------------------------------------- /Resnet2d/__init__.py: -------------------------------------------------------------------------------- 1 | __author__ = 'junqiang chen' 2 | __version__ = '1.0.0' 3 | __time__ = '2020.5.12' 4 | 5 | -------------------------------------------------------------------------------- /TNSCUI2020/Vnet2d/__init__.py: -------------------------------------------------------------------------------- 1 | __author__ = 'junqiang chen' 2 | __version__ = '1.0.0' 3 | __time__ = '2020.5.28' 4 | -------------------------------------------------------------------------------- /TNSCUI2020/Resnet2d/__init__.py: -------------------------------------------------------------------------------- 1 | __author__ = 'junqiang chen' 2 | __version__ = '1.0.0' 3 | __time__ = '2020.5.12' 4 | 5 | -------------------------------------------------------------------------------- /TNSCUI2020/dataprocess/Augmentation/__init__.py: -------------------------------------------------------------------------------- 1 | __author__ = 'junqiang chen' 2 | __version__ = '1.0.0' 3 | __time__ = '2019.2.28' 4 | -------------------------------------------------------------------------------- /TNSCUI2020/Resnet2d/log/events.out.tfevents.1590841179.WANGCHEN: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/junqiangchen/TN-SCUI2020-Challenge/HEAD/TNSCUI2020/Resnet2d/log/events.out.tfevents.1590841179.WANGCHEN -------------------------------------------------------------------------------- /TNSCUI2020/Resnet2d/log/events.out.tfevents.1590844439.WANGCHEN: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/junqiangchen/TN-SCUI2020-Challenge/HEAD/TNSCUI2020/Resnet2d/log/events.out.tfevents.1590844439.WANGCHEN -------------------------------------------------------------------------------- /TNSCUI2020/dataprocess/Augmentation/__pycache__/__init__.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/junqiangchen/TN-SCUI2020-Challenge/HEAD/TNSCUI2020/dataprocess/Augmentation/__pycache__/__init__.cpython-35.pyc -------------------------------------------------------------------------------- /TNSCUI2020/dataprocess/Augmentation/__pycache__/ImageAugmentation.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/junqiangchen/TN-SCUI2020-Challenge/HEAD/TNSCUI2020/dataprocess/Augmentation/__pycache__/ImageAugmentation.cpython-35.pyc -------------------------------------------------------------------------------- /TNSCUI2020/dataprocess/Augmentation/__pycache__/images_masks_transform.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/junqiangchen/TN-SCUI2020-Challenge/HEAD/TNSCUI2020/dataprocess/Augmentation/__pycache__/images_masks_transform.cpython-35.pyc -------------------------------------------------------------------------------- /TNSCUI2020/dataprocess/augtest.py: -------------------------------------------------------------------------------- 1 | from dataprocess.Augmentation.ImageAugmentation import DataAug, DataAugClassify 2 | 3 | 4 | def segdataAug(): 5 | aug = DataAug(rotation=20, width_shift=0.01, height_shift=0.01, rescale=1.1) 6 | aug.DataAugmentation('segmentationtraindata.csv', 4, path=r"E:\MedicalData\TNSCUI2020\segmentation\augtrain\\") 7 | 8 | 9 | def classifydataAug(): 10 | aug = DataAugClassify(rotation=20, width_shift=0.01, height_shift=0.01, rescale=1.1) 11 | aug.DataAugmentation('classifytraindata.csv', 4, path=r"E:\MedicalData\TNSCUI2020\classifiy\augtrain\\") 12 | 13 | 14 | if __name__ == '__main__': 15 | classifydataAug() 16 | print('success') 17 | -------------------------------------------------------------------------------- /vnet2d_seg_classify_train.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | os.environ["CUDA_DEVICE_ORDER"] = "PCI_BUS_ID" 4 | os.environ["CUDA_VISIBLE_DEVICES"] = "0" 5 | from tensorflow.python.client import device_lib 6 | 7 | print(device_lib.list_local_devices()) 8 | 9 | from Vnet2d.vnet_seg_classify_model import Vnet2dmutiltaskModule 10 | import numpy as np 11 | import pandas as pd 12 | 13 | 14 | def train(): 15 | ''' 16 | Preprocessing for dataset 17 | ''' 18 | # Read data set (Train data from CSV file) 19 | csvdata = pd.read_csv('dataprocess\segandclassifydata.csv') 20 | trainData = csvdata.iloc[:, :].values 21 | np.random.shuffle(trainData) 22 | labeldata = trainData[:, 0] 23 | imagedata = trainData[:, 1] 24 | maskdata = trainData[:, 2] 25 | 26 | Vnet2d = Vnet2dmutiltaskModule(512, 512, channels=1, n_class=2, costname=("dice coefficient", "cross_entropy")) 27 | Vnet2d.train(imagedata, maskdata, labeldata, "Vnet2d.pd", "log\\segclasif\\vnet2d\\", 0.001, 0.5, 30, 6) 28 | 29 | 30 | if __name__ == '__main__': 31 | train() 32 | print('success') 33 | -------------------------------------------------------------------------------- /resnet2d_train.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | os.environ["CUDA_DEVICE_ORDER"] = "PCI_BUS_ID" 4 | os.environ["CUDA_VISIBLE_DEVICES"] = "0" 5 | from tensorflow.python.client import device_lib 6 | 7 | print(device_lib.list_local_devices()) 8 | 9 | from Resnet2d.model_resNet2d import ResNet2dModule 10 | import numpy as np 11 | import pandas as pd 12 | 13 | 14 | def train(): 15 | ''' 16 | Preprocessing for dataset 17 | ''' 18 | # Read data set (Train data from CSV file) 19 | # csv file should have the type: 20 | # label,data_npy 21 | # label,data_npy 22 | # .... 23 | # 24 | train_csv = pd.read_csv('dataprocess\classifydata.csv') 25 | train_Data = train_csv.iloc[:, :].values 26 | np.random.shuffle(train_Data) 27 | # For Image 28 | trainimages = train_Data[:, 1] 29 | trainlabels = train_Data[:, 0] 30 | ResNet3d = ResNet2dModule(512, 512, channels=1, n_class=2, costname="cross_entropy") 31 | ResNet3d.train(trainimages, trainlabels, "resnet.pd", "log\\classify\\resnetcross_entropy\\", 0.001, 0.5, 30, 32 | 16) 33 | 34 | 35 | if __name__ == "__main__": 36 | train() 37 | -------------------------------------------------------------------------------- /TNSCUI2020/vnet2d_train.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | os.environ["CUDA_DEVICE_ORDER"] = "PCI_BUS_ID" 4 | os.environ["CUDA_VISIBLE_DEVICES"] = "0" 5 | from tensorflow.python.client import device_lib 6 | 7 | print(device_lib.list_local_devices()) 8 | 9 | from Vnet2d.vnet_model import Vnet2dModule 10 | import numpy as np 11 | import pandas as pd 12 | 13 | 14 | def train(): 15 | ''' 16 | Preprocessing for dataset 17 | ''' 18 | # Read data set (Train data from CSV file) 19 | csvdata = pd.read_csv(r'D:\cjq\project\python\TNSCUI2020\dataprocess\segmentationtraindata.csv') 20 | csvdataaug = pd.read_csv(r'D:\cjq\project\python\TNSCUI2020\dataprocess\segmeatationaugtraindata.csv') 21 | traindata = csvdata.iloc[:, :].values 22 | augtraindata = csvdataaug.iloc[:, :].values 23 | trainData = np.concatenate((traindata, augtraindata), axis=0) 24 | # shuffle imagedata and maskdata together 25 | np.random.shuffle(trainData) 26 | imagedata = trainData[:, 0] 27 | maskdata = trainData[:, 1] 28 | 29 | Vnet2d = Vnet2dModule(512, 512, channels=1, costname="dice coefficient") 30 | Vnet2d.train(imagedata, maskdata, "Vnet2d.pd", "log\\segmeation\\vnet2d\\", 0.001, 0.5, 5, 6) 31 | 32 | 33 | if __name__ == '__main__': 34 | train() 35 | print('success') 36 | -------------------------------------------------------------------------------- /resnet2d_inference.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | os.environ["CUDA_DEVICE_ORDER"] = "PCI_BUS_ID" 4 | os.environ["CUDA_VISIBLE_DEVICES"] = "0" 5 | from tensorflow.python.client import device_lib 6 | 7 | print(device_lib.list_local_devices()) 8 | 9 | from Resnet2d.model_resNet2d import ResNet2dModule 10 | import cv2 11 | 12 | 13 | def predict(): 14 | ResNet3d = ResNet2dModule(512, 512, channels=1, n_class=2, costname="cross_entropy", inference=True, 15 | model_path=r"log\classify\resnetcross_entropy\model\resnet.pd") 16 | test_image_path = r"E:\MedicalData\TNSCUI2020\TNSCUI2020_test\image" 17 | name = r"E:\MedicalData\TNSCUI2020\TNSCUI2020_test\classification.csv" 18 | out = open(name, 'w') 19 | out.writelines("ID" + "," + "CATE" + "\n") 20 | for number in range(1, 911, 1): 21 | imagefile = "test_" + str(number) + ".PNG" 22 | imagefilepath = os.path.join(test_image_path, imagefile) 23 | src_image = cv2.imread(imagefilepath, cv2.IMREAD_GRAYSCALE) 24 | resize_image = cv2.resize(src_image, (512, 512)) 25 | predictvalue, predict_prob = ResNet3d.prediction(resize_image / 255.) 26 | out.writelines(imagefile + "," + str(int(predictvalue[0])) + "\n") 27 | 28 | 29 | if __name__ == "__main__": 30 | predict() 31 | -------------------------------------------------------------------------------- /Vnet2d/util.py: -------------------------------------------------------------------------------- 1 | from tensorflow.python.framework import graph_util 2 | from tensorflow.python.framework import graph_io 3 | import tensorflow as tf 4 | 5 | ''' 6 | This funciton reads a '.mhd' file using SimpleITK and return the image array, origin and spacing of the image. 7 | read_Image_mask fucntion get image and mask 8 | ''' 9 | 10 | 11 | def convertMetaModelToPbModel(meta_model, pb_model): 12 | # Step 1 13 | # import the model metagraph 14 | saver = tf.train.import_meta_graph(meta_model + '.meta', clear_devices=True) 15 | # make that as the default graph 16 | graph = tf.get_default_graph() 17 | sess = tf.Session() 18 | # now restore the variables 19 | saver.restore(sess, meta_model) 20 | # Step 2 21 | # Find the output name 22 | for op in graph.get_operations(): 23 | print(op.name) 24 | # Step 3 25 | output_graph_def = graph_util.convert_variables_to_constants( 26 | sess, # The session 27 | sess.graph_def, # input_graph_def is useful for retrieving the nodes 28 | ["Input", "output/Sigmoid"]) 29 | 30 | # Step 4 31 | # output folder 32 | output_fld = './' 33 | # output pb file name 34 | output_model_file = 'model.pb' 35 | # write the graph 36 | graph_io.write_graph(output_graph_def, pb_model + output_fld, output_model_file, as_text=False) 37 | -------------------------------------------------------------------------------- /TNSCUI2020/Vnet2d/util.py: -------------------------------------------------------------------------------- 1 | from tensorflow.python.framework import graph_util 2 | from tensorflow.python.framework import graph_io 3 | import tensorflow as tf 4 | 5 | ''' 6 | This funciton reads a '.mhd' file using SimpleITK and return the image array, origin and spacing of the image. 7 | read_Image_mask fucntion get image and mask 8 | ''' 9 | 10 | 11 | def convertMetaModelToPbModel(meta_model, pb_model): 12 | # Step 1 13 | # import the model metagraph 14 | saver = tf.train.import_meta_graph(meta_model + '.meta', clear_devices=True) 15 | # make that as the default graph 16 | graph = tf.get_default_graph() 17 | sess = tf.Session() 18 | # now restore the variables 19 | saver.restore(sess, meta_model) 20 | # Step 2 21 | # Find the output name 22 | for op in graph.get_operations(): 23 | print(op.name) 24 | # Step 3 25 | output_graph_def = graph_util.convert_variables_to_constants( 26 | sess, # The session 27 | sess.graph_def, # input_graph_def is useful for retrieving the nodes 28 | ["Input", "output/Sigmoid"]) 29 | 30 | # Step 4 31 | # output folder 32 | output_fld = './' 33 | # output pb file name 34 | output_model_file = 'model.pb' 35 | # write the graph 36 | graph_io.write_graph(output_graph_def, pb_model + output_fld, output_model_file, as_text=False) 37 | -------------------------------------------------------------------------------- /TNSCUI2020/resnet2d_train.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | os.environ["CUDA_DEVICE_ORDER"] = "PCI_BUS_ID" 4 | os.environ["CUDA_VISIBLE_DEVICES"] = "0" 5 | from tensorflow.python.client import device_lib 6 | 7 | print(device_lib.list_local_devices()) 8 | 9 | from Resnet2d.model_resNet2d import ResNet2dModule 10 | import numpy as np 11 | import pandas as pd 12 | 13 | 14 | def train(): 15 | ''' 16 | Preprocessing for dataset 17 | ''' 18 | # Read data set (Train data from CSV file) 19 | # csv file should have the type: 20 | # label,data_npy 21 | # label,data_npy 22 | # .... 23 | # 24 | train_augcvs = pd.read_csv(r'D:\cjq\project\python\TNSCUI2020\dataprocess\classifyaugtraindata.csv') 25 | train_csv = pd.read_csv(r'D:\cjq\project\python\TNSCUI2020\dataprocess\classifytraindata.csv') 26 | 27 | train_aug = train_augcvs.iloc[:, :].values 28 | train = train_csv.iloc[:, :].values 29 | train_Data = np.concatenate((train_aug, train), axis=0) 30 | np.random.shuffle(train_Data) 31 | # For Image 32 | trainimages = train_Data[:, 1] 33 | trainlabels = train_Data[:, 0] 34 | ResNet3d = ResNet2dModule(512, 512, channels=1, n_class=2, costname="cross_entropy") 35 | ResNet3d.train(trainimages, trainlabels, "resnet.pd", "log\\classify\\resnet\\", 0.001, 0.5, 10, 16) 36 | 37 | 38 | if __name__ == "__main__": 39 | train() 40 | -------------------------------------------------------------------------------- /TNSCUI2020/dataprocess/data2dprepare.py: -------------------------------------------------------------------------------- 1 | import cv2 2 | import numpy as np 3 | from dataprocess.utils import file_name_path 4 | import pandas as pd 5 | 6 | 7 | def analyse_image(input_path): 8 | image = "image" 9 | file_image_dir = input_path + "/" + image 10 | 11 | file_paths = file_name_path(file_image_dir, dir=False, file=True) 12 | 13 | size = [] 14 | for index in range(len(file_paths)): 15 | file_image_path = file_image_dir + "/" + file_paths[index] 16 | image = cv2.imread(file_image_path, 0) 17 | print(image.shape) 18 | size.append(np.array(image.shape)) 19 | print("mean size:", (np.mean(np.array(size), axis=0))) 20 | 21 | 22 | def splitclassifyintotraintest(file_name): 23 | classify = r'E:\MedicalData\TNSCUI2020\TNSCUI2020_train\train.csv' 24 | image_path = r"E:\MedicalData\TNSCUI2020\TNSCUI2020_train\image" 25 | csvdata = pd.read_csv(classify) 26 | traindata = csvdata.iloc[:, :].values 27 | imagedata = traindata[:, 0] 28 | labeldata = traindata[:, 1] 29 | out = open(file_name, 'w') 30 | out.writelines("label,Image" + "\n") 31 | for index in range(len(imagedata)): 32 | out.writelines(str(labeldata[index]) + "," + image_path + "/" + str(imagedata[index]) + "\n") 33 | 34 | 35 | if __name__ == '__main__': 36 | # analyse_image(r'E:\MedicalData\TNSCUI2020\TNSCUI2020_train') 37 | splitclassifyintotraintest("classifydata.csv") 38 | print('success') 39 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # TN-SCUI2020-Challenge 2 | > This is an example of the Us imaging is used to segment and classify thyroid nodule. 3 | ![](tnscui2.png) 4 | 5 | ## Prerequisities 6 | The following dependencies are needed: 7 | - numpy >= 1.11.1 8 | - SimpleITK >=1.0.1 9 | - tensorflow-gpu ==1.14.0 10 | - pandas >=0.20.1 11 | - scikit-learn >= 0.17.1 12 | 13 | ## How to Use 14 | * 1、when download the all project,check out the segmeatationdata.csv and classifydata.csv,put your train data into same folder. 15 | * 2、run vnet2d_train.py for vnet2d segmeatation training:make sure train data have effective path 16 | * 3、run vnet2d_inference.py for vnet2d segmeatation inference:make sure test data have effective path 17 | * 4、run resnet2d_train.py for resnet2d classify training:make sure train data have effective path 18 | * 5、run resnet2d_inference.py for resnet2d classify inference:make sure test data have effective path 19 | 20 | ## Result 21 | 22 | * segment train loss and train accuracy 23 | ![](loss.PNG) 24 | 25 | * classify train loss and train accuracy 26 | ![](loss2.PNG) 27 | 28 | * test dataset segmentation result:left is source image,median is ground truth mask,right is predict mask 29 | ![](分割结果.png) 30 | 31 | * test dataset leadboard 32 | ![](leadboard.png) 33 | 34 | * more detail and trained model can follow my WeChat Public article. 35 | 36 | ## Contact 37 | * https://github.com/junqiangchen 38 | * email: 1207173174@qq.com 39 | * Contact: junqiangChen 40 | * WeChat Number: 1207173174 41 | * WeChat Public number: 最新医学影像技术 42 | -------------------------------------------------------------------------------- /vnet2d_train.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | os.environ["CUDA_DEVICE_ORDER"] = "PCI_BUS_ID" 4 | os.environ["CUDA_VISIBLE_DEVICES"] = "0" 5 | from tensorflow.python.client import device_lib 6 | 7 | print(device_lib.list_local_devices()) 8 | 9 | from Vnet2d.vnet_model import Vnet2dModule, AGVnet2dModule 10 | import numpy as np 11 | import pandas as pd 12 | 13 | 14 | def train(): 15 | ''' 16 | Preprocessing for dataset 17 | ''' 18 | # Read data set (Train data from CSV file) 19 | csvdata = pd.read_csv('dataprocess\segandclassifydata.csv') 20 | trainData = csvdata.iloc[:, :].values 21 | np.random.shuffle(trainData) 22 | labeldata = trainData[:, 0] 23 | imagedata = trainData[:, 1] 24 | maskdata = trainData[:, 2] 25 | 26 | Vnet2d = Vnet2dModule(512, 512, channels=1, costname="dice coefficient") 27 | Vnet2d.train(imagedata, maskdata, "Vnet2d.pd", "log\\segmeation\\vnet2d\\", 0.001, 0.5, 10, 6) 28 | 29 | 30 | def trainag(): 31 | ''' 32 | Preprocessing for dataset 33 | ''' 34 | # Read data set (Train data from CSV file) 35 | csvdata = pd.read_csv('dataprocess\segandclassifydata.csv') 36 | trainData = csvdata.iloc[:, :].values 37 | np.random.shuffle(trainData) 38 | labeldata = trainData[:, 0] 39 | imagedata = trainData[:, 1] 40 | maskdata = trainData[:, 2] 41 | 42 | agVnet2d = AGVnet2dModule(512, 512, channels=1, costname="dice coefficient") 43 | agVnet2d.train(imagedata, maskdata, "agVnet2d.pd", "log\\segmeation\\agvnet2d\\", 0.001, 0.5, 10, 5) 44 | 45 | 46 | if __name__ == '__main__': 47 | train() 48 | print('success') 49 | -------------------------------------------------------------------------------- /TNSCUI2020/resnet2d_predict.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | os.environ["CUDA_DEVICE_ORDER"] = "PCI_BUS_ID" 4 | os.environ["CUDA_VISIBLE_DEVICES"] = "0" 5 | from tensorflow.python.client import device_lib 6 | 7 | print(device_lib.list_local_devices()) 8 | 9 | from Resnet2d.model_resNet2d import ResNet2dModule 10 | import cv2 11 | import pandas as pd 12 | import numpy as np 13 | 14 | 15 | def predict(): 16 | test_datacsv = pd.read_csv(r'D:\cjq\project\python\TNSCUI2020\dataprocess\classifytestdata.csv') 17 | test_data = test_datacsv.iloc[:, :].values 18 | # For Image 19 | images = test_data[:, 1] 20 | # For Labels 21 | labels = test_data[:, 0] 22 | ResNet3d = ResNet2dModule(512, 512, channels=1, n_class=2, costname="cross_entropy", inference=True, 23 | model_path=r"log\classify\resnet\model\resnet.pd-100000") 24 | 25 | predictvalues = [] 26 | predict_probs = [] 27 | for num in range(len(images)): 28 | src_image = cv2.imread(images[num], 0) 29 | resize_image = cv2.resize(src_image, (512, 512)) 30 | predictvalue, predict_prob = ResNet3d.prediction(resize_image / 255.) 31 | predictvalues.append(predictvalue) 32 | predict_probs.append(predict_prob) 33 | 34 | name = 'classify_metrics.csv' 35 | out = open(name, 'w') 36 | out.writelines("y_predict" + "," + "y_score" + "," + "y_true" + "\n") 37 | labels = labels.tolist() 38 | for index in range(np.shape(images)[0]): 39 | out.writelines( 40 | str(predictvalues[index][0]) + "," + str(predict_probs[index][0]) + "," + str(labels[index]) + "\n") 41 | 42 | 43 | if __name__ == "__main__": 44 | predict() 45 | -------------------------------------------------------------------------------- /vnet2d_seg_classify_inference.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | os.environ["CUDA_DEVICE_ORDER"] = "PCI_BUS_ID" 4 | os.environ["CUDA_VISIBLE_DEVICES"] = "0" 5 | from tensorflow.python.client import device_lib 6 | 7 | print(device_lib.list_local_devices()) 8 | 9 | from Vnet2d.vnet_seg_classify_model import Vnet2dmutiltaskModule 10 | from dataprocess.utils import calcu_iou 11 | import cv2 12 | import os 13 | import numpy as np 14 | 15 | 16 | def predict_test(): 17 | name = r"E:\MedicalData\TNSCUI2020\TNSCUI2020_test\seg_classifyvnetmask.csv" 18 | out = open(name, 'w') 19 | out.writelines("ID" + "," + "CATE" + "\n") 20 | Vnet2d = Vnet2dmutiltaskModule(512, 512, channels=1, n_class=2, costname=("dice coefficient", "cross_entropy"), 21 | inference=True, model_path="log\segclasif\\vnet2d\model\Vnet2d.pd") 22 | test_image_path = r"E:\MedicalData\TNSCUI2020\TNSCUI2020_test\image" 23 | test_mask_path = r"E:\MedicalData\TNSCUI2020\TNSCUI2020_test\seg_classifyvnetmask" 24 | for number in range(1, 911, 1): 25 | imagefile = "test_" + str(number) + ".PNG" 26 | imagefilepath = os.path.join(test_image_path, imagefile) 27 | src_image = cv2.imread(imagefilepath, cv2.IMREAD_GRAYSCALE) 28 | resize_image = cv2.resize(src_image, (512, 512)) 29 | pd_mask_image, label_image = Vnet2d.prediction(resize_image / 255.) 30 | new_mask_image = cv2.resize(pd_mask_image, (src_image.shape[1], src_image.shape[0])) 31 | maskfilepath = os.path.join(test_mask_path, imagefile) 32 | cv2.imwrite(maskfilepath, new_mask_image) 33 | out.writelines(imagefile + "," + str(label_image[0]) + "\n") 34 | 35 | 36 | if __name__ == "__main__": 37 | predict_test() 38 | print('success') 39 | -------------------------------------------------------------------------------- /TNSCUI2020/vnet2d_predict.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | os.environ["CUDA_DEVICE_ORDER"] = "PCI_BUS_ID" 4 | os.environ["CUDA_VISIBLE_DEVICES"] = "0" 5 | from tensorflow.python.client import device_lib 6 | 7 | print(device_lib.list_local_devices()) 8 | 9 | from Vnet2d.vnet_model import Vnet2dModule 10 | from dataprocess.utils import calcu_iou 11 | import cv2 12 | import pandas as pd 13 | import numpy as np 14 | 15 | 16 | def predict_test(): 17 | Vnet2d = Vnet2dModule(512, 512, channels=1, costname="dice coefficient", inference=True, 18 | model_path="log\segmeation\\vnet2d\model\\Vnet2d.pd") 19 | csvdata = pd.read_csv(r'D:\cjq\project\python\TNSCUI2020\dataprocess\segmentationtestdata.csv') 20 | traindata = csvdata.iloc[:, :].values 21 | imagedata = traindata[:, 0] 22 | maskdata = traindata[:, 1] 23 | iou_values = [] 24 | for i in range(len(imagedata)): 25 | src_image = cv2.imread(imagedata[i], cv2.IMREAD_GRAYSCALE) 26 | mask_image = cv2.imread(maskdata[i], cv2.IMREAD_GRAYSCALE) 27 | resize_image = cv2.resize(src_image, (512, 512)) 28 | pd_mask_image = Vnet2d.prediction(resize_image / 255.) 29 | pd_mask_image[pd_mask_image >= 128] = 255 30 | pd_mask_image[pd_mask_image < 128] = 0 31 | new_mask_image = cv2.resize(pd_mask_image, (mask_image.shape[1], mask_image.shape[0])) 32 | cv2.imwrite("E:\MedicalData\TNSCUI2020\TNSCUI2020_train\\" + str(i) + "image.bmp", src_image) 33 | cv2.imwrite("E:\MedicalData\TNSCUI2020\TNSCUI2020_train\\" + str(i) + "mask.bmp", mask_image) 34 | cv2.imwrite("E:\MedicalData\TNSCUI2020\TNSCUI2020_train\\" + str(i) + "pdmask.bmp", new_mask_image) 35 | iou_value = calcu_iou(mask_image, new_mask_image, 255) 36 | iou_values.append(iou_value) 37 | print("mean iou:", np.mean(iou_values)) 38 | 39 | 40 | if __name__ == "__main__": 41 | predict_test() 42 | print('success') 43 | -------------------------------------------------------------------------------- /vnet2d_inference.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | os.environ["CUDA_DEVICE_ORDER"] = "PCI_BUS_ID" 4 | os.environ["CUDA_VISIBLE_DEVICES"] = "-1" 5 | from tensorflow.python.client import device_lib 6 | 7 | print(device_lib.list_local_devices()) 8 | 9 | from Vnet2d.vnet_model import Vnet2dModule, AGVnet2dModule 10 | from dataprocess.utils import calcu_iou 11 | import cv2 12 | import os 13 | import numpy as np 14 | 15 | 16 | def predict_test(): 17 | Vnet2d = Vnet2dModule(512, 512, channels=1, costname="dice coefficient", inference=True, 18 | model_path="log\segmeation\\vnet2d\model\Vnet2d.pd") 19 | test_image_path = r"E:\MedicalData\TNSCUI2020\TNSCUI2020_test\image" 20 | test_mask_path = r"E:\MedicalData\TNSCUI2020\TNSCUI2020_test\vnet_mask" 21 | allimagefiles = os.listdir(test_image_path) 22 | for imagefile in allimagefiles: 23 | imagefilepath = os.path.join(test_image_path, imagefile) 24 | src_image = cv2.imread(imagefilepath, cv2.IMREAD_GRAYSCALE) 25 | resize_image = cv2.resize(src_image, (512, 512)) 26 | pd_mask_image = Vnet2d.prediction(resize_image / 255.) 27 | new_mask_image = cv2.resize(pd_mask_image, (src_image.shape[1], src_image.shape[0])) 28 | maskfilepath = os.path.join(test_mask_path, imagefile) 29 | cv2.imwrite(maskfilepath, new_mask_image) 30 | 31 | 32 | def predict_testag(): 33 | Vnet2d = AGVnet2dModule(512, 512, channels=1, costname="dice coefficient", inference=True, 34 | model_path="log\segmeation\\agvnet2d\model\\agVnet2d.pd") 35 | test_image_path = r"E:\MedicalData\TNSCUI2020\TNSCUI2020_test\image" 36 | test_mask_path = r"E:\MedicalData\TNSCUI2020\TNSCUI2020_test\agvnet_mask" 37 | allimagefiles = os.listdir(test_image_path) 38 | for imagefile in allimagefiles: 39 | imagefilepath = os.path.join(test_image_path, imagefile) 40 | src_image = cv2.imread(imagefilepath, cv2.IMREAD_GRAYSCALE) 41 | resize_image = cv2.resize(src_image, (512, 512)) 42 | pd_mask_image = Vnet2d.prediction(resize_image / 255.) 43 | new_mask_image = cv2.resize(pd_mask_image, (src_image.shape[1], src_image.shape[0])) 44 | maskfilepath = os.path.join(test_mask_path, imagefile) 45 | cv2.imwrite(maskfilepath, new_mask_image) 46 | 47 | 48 | if __name__ == "__main__": 49 | predict_test() 50 | # predict_testag() 51 | print('success') 52 | -------------------------------------------------------------------------------- /TNSCUI2020/dataprocess/utils.py: -------------------------------------------------------------------------------- 1 | import os 2 | import numpy as np 3 | 4 | 5 | def calcu_dice(Y_pred, Y_gt, K=255): 6 | """ 7 | calculate two input dice value 8 | :param Y_pred: 9 | :param Y_gt: 10 | :param K: 11 | :return: 12 | """ 13 | intersection = 2 * np.sum(Y_pred[Y_gt == K]) 14 | denominator = np.sum(Y_pred) + np.sum(Y_gt) 15 | loss = (intersection / denominator) 16 | return loss 17 | 18 | 19 | def calcu_iou(Y_pred, Y_gt, K=255): 20 | """ 21 | calculate two input iou value 22 | :param Y_pred: 23 | :param Y_gt: 24 | :param K: 25 | :return: 26 | """ 27 | intersection = np.sum(Y_pred[Y_gt == K]) 28 | denominator = np.sum(Y_pred) + np.sum(Y_gt) - intersection 29 | loss = (intersection / denominator) 30 | return loss 31 | 32 | 33 | def file_name_path(file_dir, dir=True, file=False): 34 | """ 35 | get root path,sub_dirs,all_sub_files 36 | :param file_dir: 37 | :return: 38 | """ 39 | for root, dirs, files in os.walk(file_dir): 40 | if len(dirs) and dir: 41 | print("sub_dirs:", dirs) 42 | return dirs 43 | if len(files) and file: 44 | print("files:", files) 45 | return files 46 | 47 | 48 | def save_file2csv(file_dir, file_name): 49 | """ 50 | save file path to csv 51 | :param file_dir:preprocess data path 52 | :param file_name:output csv name 53 | :return: 54 | """ 55 | out = open(file_name, 'w') 56 | image = "image" 57 | mask = "mask" 58 | file_image_dir = file_dir + "/" + image 59 | file_mask_dir = file_dir + "/" + mask 60 | file_paths = file_name_path(file_image_dir, dir=False, file=True) 61 | out.writelines("Image,Mask" + "\n") 62 | for index in range(len(file_paths)): 63 | out_file_image_path = file_image_dir + "/" + file_paths[index] 64 | out_file_mask_path = file_mask_dir + "/" + file_paths[index] 65 | out.writelines(out_file_image_path + "," + out_file_mask_path + "\n") 66 | 67 | 68 | def save_file2csvclassify(file_dir, file_name, labelnum=2): 69 | """ 70 | save file path to csv 71 | :param file_dir:preprocess data path 72 | :param file_name:output csv name 73 | :return: 74 | """ 75 | out = open(file_name, 'w') 76 | out.writelines("label,Image" + "\n") 77 | for i in range(labelnum): 78 | file_image_dir = file_dir + "/" + str(i) 79 | file_paths = file_name_path(file_image_dir, dir=False, file=True) 80 | for index in range(len(file_paths)): 81 | out_file_image_path = file_image_dir + "/" + file_paths[index] 82 | out.writelines(str(i) + "," + out_file_image_path + "\n") 83 | 84 | 85 | if __name__ == '__main__': 86 | # save_file2csv(r"E:\MedicalData\TNSCUI2020\segmentation\augtrain", "segmeatationaugtraindata.csv") 87 | save_file2csvclassify(r"E:\MedicalData\TNSCUI2020\classifiy\augtrain", "classifyaugtraindata.csv") 88 | print('success') 89 | -------------------------------------------------------------------------------- /TNSCUI2020/dataprocess/subset.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import os, sys, math, random 4 | from collections import defaultdict 5 | 6 | if sys.version_info[0] >= 3: 7 | xrange = range 8 | 9 | def exit_with_help(argv): 10 | print("""\ 11 | Usage: {0} [options] dataset subset_size [output1] [output2] 12 | 13 | This script randomly selects a subset of the dataset. 14 | 15 | options: 16 | -s method : method of selection (default 0) 17 | 0 -- stratified selection (classification only) 18 | 1 -- random selection 19 | 20 | output1 : the subset (optional) 21 | output2 : rest of the data (optional) 22 | If output1 is omitted, the subset will be printed on the screen.""".format(argv[0])) 23 | exit(1) 24 | 25 | def process_options(argv): 26 | argc = len(argv) 27 | if argc < 3: 28 | exit_with_help(argv) 29 | 30 | # default method is stratified selection 31 | method = 0 32 | subset_file = sys.stdout 33 | rest_file = None 34 | 35 | i = 1 36 | while i < argc: 37 | if argv[i][0] != "-": 38 | break 39 | if argv[i] == "-s": 40 | i = i + 1 41 | method = int(argv[i]) 42 | if method not in [0,1]: 43 | print("Unknown selection method {0}".format(method)) 44 | exit_with_help(argv) 45 | i = i + 1 46 | 47 | dataset = argv[i] 48 | subset_size = int(argv[i+1]) 49 | if i+2 < argc: 50 | subset_file = open(argv[i+2],'w') 51 | if i+3 < argc: 52 | rest_file = open(argv[i+3],'w') 53 | 54 | return dataset, subset_size, method, subset_file, rest_file 55 | 56 | def random_selection(dataset, subset_size): 57 | l = sum(1 for line in open(dataset,'r')) 58 | return sorted(random.sample(xrange(l), subset_size)) 59 | 60 | def stratified_selection(dataset, subset_size): 61 | labels = [line.split(None,1)[0] for line in open(dataset)] 62 | label_linenums = defaultdict(list) 63 | for i, label in enumerate(labels): 64 | label_linenums[label] += [i] 65 | 66 | l = len(labels) 67 | remaining = subset_size 68 | ret = [] 69 | 70 | # classes with fewer data are sampled first; otherwise 71 | # some rare classes may not be selected 72 | for label in sorted(label_linenums, key=lambda x: len(label_linenums[x])): 73 | linenums = label_linenums[label] 74 | label_size = len(linenums) 75 | # at least one instance per class 76 | s = int(min(remaining, max(1, math.ceil(label_size*(float(subset_size)/l))))) 77 | if s == 0: 78 | sys.stderr.write('''\ 79 | Error: failed to have at least one instance per class 80 | 1. You may have regression data. 81 | 2. Your classification data is unbalanced or too small. 82 | Please use -s 1. 83 | ''') 84 | sys.exit(-1) 85 | remaining -= s 86 | ret += [linenums[i] for i in random.sample(xrange(label_size), s)] 87 | return sorted(ret) 88 | 89 | def main(argv=sys.argv): 90 | dataset, subset_size, method, subset_file, rest_file = process_options(argv) 91 | #uncomment the following line to fix the random seed 92 | #random.seed(0) 93 | selected_lines = [] 94 | 95 | if method == 0: 96 | selected_lines = stratified_selection(dataset, subset_size) 97 | elif method == 1: 98 | selected_lines = random_selection(dataset, subset_size) 99 | 100 | #select instances based on selected_lines 101 | dataset = open(dataset,'r') 102 | prev_selected_linenum = -1 103 | for i in xrange(len(selected_lines)): 104 | for cnt in xrange(selected_lines[i]-prev_selected_linenum-1): 105 | line = dataset.readline() 106 | if rest_file: 107 | rest_file.write(line) 108 | subset_file.write(dataset.readline()) 109 | prev_selected_linenum = selected_lines[i] 110 | subset_file.close() 111 | 112 | if rest_file: 113 | for line in dataset: 114 | rest_file.write(line) 115 | rest_file.close() 116 | dataset.close() 117 | 118 | if __name__ == '__main__': 119 | main(sys.argv) 120 | 121 | -------------------------------------------------------------------------------- /Resnet2d/classify_metrics.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | os.environ["CUDA_DEVICE_ORDER"] = "PCI_BUS_ID" 4 | os.environ["CUDA_VISIBLE_DEVICES"] = "-1" 5 | from tensorflow.python.client import device_lib 6 | 7 | print(device_lib.list_local_devices()) 8 | from sklearn.metrics import confusion_matrix 9 | from sklearn.metrics import classification_report 10 | from sklearn.metrics import roc_auc_score 11 | import pandas as pd 12 | import tensorflow as tf 13 | 14 | 15 | class tf_roc(object): 16 | def __init__(self, y_pred_prob, y_true, threshold_num, save_dir): 17 | ''' 18 | file format: dataid,predict_score,label 19 | predict_score should be between 0 and 1 20 | label should be 0 or 1 21 | threshold_num: number of threshold will plot 22 | ''' 23 | self.predicts = y_pred_prob.tolist() 24 | self.labels = y_true.tolist() 25 | self.total = y_true.shape[0] 26 | 27 | self.threshold_num = threshold_num 28 | self.trues = 0 # total of True labels 29 | self.fpr = [] # false positive 30 | self.tpr = [] # true positive 31 | self.ths = [] # thresholds 32 | self.save_dir = save_dir 33 | self.writer = tf.summary.FileWriter(self.save_dir) 34 | 35 | def calc(self): 36 | for label in self.labels: 37 | if label: 38 | self.trues += 1 39 | threshold_step = 1. / self.threshold_num 40 | for t in range(self.threshold_num + 1): 41 | th = 1 - threshold_step * t 42 | tn, tp, fp, fpr, tpr = self._calc_once(th) 43 | self.fpr.append(fpr) 44 | self.tpr.append(tpr) 45 | self.ths.append(th) 46 | self._save(fpr, tpr) 47 | print(self.fpr) 48 | print(self.tpr) 49 | print(self.ths) 50 | 51 | def _save(self, fpr, tpr): 52 | summt = tf.Summary() 53 | summt.value.add(tag="roc", simple_value=tpr) 54 | self.writer.add_summary(summt, fpr * 100) # for tensorboard step drawable 55 | self.writer.flush() 56 | 57 | def _calc_once(self, t): 58 | esp = 1e-5 59 | fp = 0 60 | tp = 0 61 | tn = 0 62 | for i in range(self.total): 63 | if not self.labels[i]: 64 | if self.predicts[i] >= t: 65 | fp += 1 66 | else: 67 | tn += 1 68 | elif self.predicts[i] >= t: 69 | tp += 1 70 | # fpr = fp / float(fp + tn) #precision 71 | fpr = fp / float(fp + tp + esp) # detection 72 | tpr = tp / float(self.trues) 73 | return tn, tp, fp, fpr, tpr 74 | 75 | 76 | def classification_reports(y_true, y_pred): 77 | print("classification_report(left:labels):") 78 | print(classification_report(y_true=y_true, y_pred=y_pred)) 79 | 80 | 81 | def confusion_matrixs(y_true, y_pred): 82 | conf_mat = confusion_matrix(y_true, y_pred) 83 | print("confusion _matrixs(left labels:y_true,up labels:y_pred):") 84 | print(conf_mat) 85 | 86 | 87 | def roc_auc_scores(y_true, y_pred_prob): 88 | return roc_auc_score(y_true=y_true, y_score=y_pred_prob) 89 | 90 | 91 | def classify_metric_message(predict_label_file): 92 | """ 93 | :param predict_label_file:should have type:predict_label,predict_prob,true_label 94 | :param name: 95 | :return: 96 | """ 97 | csvimagedata = pd.read_csv(predict_label_file) 98 | data = csvimagedata.iloc[:, :].values 99 | predict_labels = data[:, 0] 100 | predict_probs = data[:, 1] 101 | true_labels = data[:, 2] 102 | 103 | print("roc_auc_score") 104 | print(roc_auc_scores(true_labels, predict_probs)) 105 | print("confusion_matric") 106 | confusion_matrixs(true_labels, predict_labels) 107 | print("main_classify") 108 | classification_reports(true_labels, predict_labels) 109 | print("roc_curve") 110 | threshold_num = 100 111 | save_dir = "log" 112 | roc = tf_roc(predict_probs, true_labels, int(threshold_num), save_dir) 113 | roc.calc() 114 | 115 | 116 | if __name__ == '__main__': 117 | predict_label_file = "classify_metrics.csv" 118 | classify_metric_message(predict_label_file) 119 | -------------------------------------------------------------------------------- /TNSCUI2020/Resnet2d/classify_metrics.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | os.environ["CUDA_DEVICE_ORDER"] = "PCI_BUS_ID" 4 | os.environ["CUDA_VISIBLE_DEVICES"] = "-1" 5 | from tensorflow.python.client import device_lib 6 | 7 | print(device_lib.list_local_devices()) 8 | from sklearn.metrics import confusion_matrix 9 | from sklearn.metrics import classification_report 10 | from sklearn.metrics import roc_auc_score 11 | import pandas as pd 12 | import tensorflow as tf 13 | 14 | 15 | class tf_roc(object): 16 | def __init__(self, y_pred_prob, y_true, threshold_num, save_dir): 17 | ''' 18 | file format: dataid,predict_score,label 19 | predict_score should be between 0 and 1 20 | label should be 0 or 1 21 | threshold_num: number of threshold will plot 22 | ''' 23 | self.predicts = y_pred_prob.tolist() 24 | self.labels = y_true.tolist() 25 | self.total = y_true.shape[0] 26 | 27 | self.threshold_num = threshold_num 28 | self.trues = 0 # total of True labels 29 | self.fpr = [] # false positive 30 | self.tpr = [] # true positive 31 | self.ths = [] # thresholds 32 | self.save_dir = save_dir 33 | self.writer = tf.summary.FileWriter(self.save_dir) 34 | 35 | def calc(self): 36 | for label in self.labels: 37 | if label: 38 | self.trues += 1 39 | threshold_step = 1. / self.threshold_num 40 | for t in range(self.threshold_num + 1): 41 | th = 1 - threshold_step * t 42 | tn, tp, fp, fpr, tpr = self._calc_once(th) 43 | self.fpr.append(fpr) 44 | self.tpr.append(tpr) 45 | self.ths.append(th) 46 | self._save(fpr, tpr) 47 | print(self.fpr) 48 | print(self.tpr) 49 | print(self.ths) 50 | 51 | def _save(self, fpr, tpr): 52 | summt = tf.Summary() 53 | summt.value.add(tag="roc", simple_value=tpr) 54 | self.writer.add_summary(summt, fpr * 100) # for tensorboard step drawable 55 | self.writer.flush() 56 | 57 | def _calc_once(self, t): 58 | esp = 1e-5 59 | fp = 0 60 | tp = 0 61 | tn = 0 62 | for i in range(self.total): 63 | if not self.labels[i]: 64 | if self.predicts[i] >= t: 65 | fp += 1 66 | else: 67 | tn += 1 68 | elif self.predicts[i] >= t: 69 | tp += 1 70 | # fpr = fp / float(fp + tn) #precision 71 | fpr = fp / float(fp + tp + esp) # detection 72 | tpr = tp / float(self.trues) 73 | return tn, tp, fp, fpr, tpr 74 | 75 | 76 | def classification_reports(y_true, y_pred): 77 | print("classification_report(left:labels):") 78 | print(classification_report(y_true=y_true, y_pred=y_pred)) 79 | 80 | 81 | def confusion_matrixs(y_true, y_pred): 82 | conf_mat = confusion_matrix(y_true, y_pred) 83 | print("confusion _matrixs(left labels:y_true,up labels:y_pred):") 84 | print(conf_mat) 85 | 86 | 87 | def roc_auc_scores(y_true, y_pred_prob): 88 | return roc_auc_score(y_true=y_true, y_score=y_pred_prob) 89 | 90 | 91 | def classify_metric_message(predict_label_file): 92 | """ 93 | :param predict_label_file:should have type:predict_label,predict_prob,true_label 94 | :param name: 95 | :return: 96 | """ 97 | csvimagedata = pd.read_csv(predict_label_file) 98 | data = csvimagedata.iloc[:, :].values 99 | predict_labels = data[:, 0] 100 | predict_probs = data[:, 1] 101 | true_labels = data[:, 2] 102 | 103 | print("roc_auc_score") 104 | print(roc_auc_scores(true_labels, predict_probs)) 105 | print("confusion_matric") 106 | confusion_matrixs(true_labels, predict_labels) 107 | print("main_classify") 108 | classification_reports(true_labels, predict_labels) 109 | print("roc_curve") 110 | threshold_num = 100 111 | save_dir = "log" 112 | roc = tf_roc(predict_probs, true_labels, int(threshold_num), save_dir) 113 | roc.calc() 114 | 115 | 116 | if __name__ == '__main__': 117 | predict_label_file = "classify_metrics.csv" 118 | classify_metric_message(predict_label_file) 119 | -------------------------------------------------------------------------------- /TNSCUI2020/Vnet2d/layer.py: -------------------------------------------------------------------------------- 1 | ''' 2 | covlution layer,pool layer,initialization。。。。 3 | ''' 4 | from __future__ import division 5 | import tensorflow as tf 6 | import numpy as np 7 | 8 | 9 | # Weight initialization (Xavier's init) 10 | def weight_xavier_init(shape, n_inputs, n_outputs, activefunction='sigomd', uniform=True, variable_name=None): 11 | if activefunction == 'sigomd': 12 | if uniform: 13 | init_range = tf.sqrt(6.0 / (n_inputs + n_outputs)) 14 | initial = tf.random_uniform(shape, -init_range, init_range) 15 | return tf.get_variable(name=variable_name, initializer=initial, trainable=True) 16 | else: 17 | stddev = tf.sqrt(2.0 / (n_inputs + n_outputs)) 18 | initial = tf.truncated_normal(shape, mean=0.0, stddev=stddev) 19 | return tf.get_variable(name=variable_name, initializer=initial, trainable=True) 20 | elif activefunction == 'relu': 21 | if uniform: 22 | init_range = tf.sqrt(6.0 / (n_inputs + n_outputs)) * np.sqrt(2) 23 | initial = tf.random_uniform(shape, -init_range, init_range) 24 | return tf.get_variable(name=variable_name, initializer=initial, trainable=True) 25 | else: 26 | stddev = tf.sqrt(2.0 / (n_inputs + n_outputs)) * np.sqrt(2) 27 | initial = tf.truncated_normal(shape, mean=0.0, stddev=stddev) 28 | return tf.get_variable(name=variable_name, initializer=initial, trainable=True) 29 | elif activefunction == 'tan': 30 | if uniform: 31 | init_range = tf.sqrt(6.0 / (n_inputs + n_outputs)) * 4 32 | initial = tf.random_uniform(shape, -init_range, init_range) 33 | return tf.get_variable(name=variable_name, initializer=initial, trainable=True) 34 | else: 35 | stddev = tf.sqrt(2.0 / (n_inputs + n_outputs)) * 4 36 | initial = tf.truncated_normal(shape, mean=0.0, stddev=stddev) 37 | return tf.get_variable(name=variable_name, initializer=initial, trainable=True) 38 | 39 | 40 | # Bias initialization 41 | def bias_variable(shape, variable_name=None): 42 | initial = tf.constant(0.1, shape=shape) 43 | return tf.get_variable(name=variable_name, initializer=initial, trainable=True) 44 | 45 | 46 | # 2D convolution 47 | def conv2d(x, W, strides=1): 48 | conv_2d = tf.nn.conv2d(x, W, strides=[1, strides, strides, 1], padding='SAME') 49 | return conv_2d 50 | 51 | 52 | def normalizationlayer(x, is_train, height=None, width=None, norm_type='None', G=16, esp=1e-5, scope=None): 53 | with tf.name_scope(scope + norm_type): 54 | if norm_type == 'None': 55 | output = x 56 | elif norm_type == 'batch': 57 | output = tf.contrib.layers.batch_norm(x, center=True, scale=True, is_training=is_train) 58 | elif norm_type == 'group': 59 | # tranpose:[bs,h,w,c]to[bs,c,h,w]follwing the paper 60 | x = tf.transpose(x, [0, 3, 1, 2]) 61 | N, C, H, W = x.get_shape().as_list() 62 | G = min(G, C) 63 | if H == None and W == None: 64 | H, W = height, width 65 | x = tf.reshape(x, [-1, G, C // G, H, W]) 66 | mean, var = tf.nn.moments(x, [2, 3, 4], keep_dims=True) 67 | x = (x - mean) / tf.sqrt(var + esp) 68 | # per channel gama and beta 69 | gama = tf.get_variable(scope + norm_type + 'group_gama', [C], initializer=tf.constant_initializer(1.0)) 70 | beta = tf.get_variable(scope + norm_type + 'group_beta', [C], initializer=tf.constant_initializer(0.0)) 71 | gama = tf.reshape(gama, [1, C, 1, 1]) 72 | beta = tf.reshape(beta, [1, C, 1, 1]) 73 | output = tf.reshape(x, [-1, C, H, W]) * gama + beta 74 | # tranpose:[bs,c,h,w]to[bs,h,w,c]follwing the paper 75 | output = tf.transpose(output, [0, 2, 3, 1]) 76 | return output 77 | 78 | 79 | # 2D upsampling 80 | def upsample2d(x, scale_factor, scope=None): 81 | '''' 82 | X shape is [nsample,rows, cols, channel] 83 | out shape is[nsample,rows*scale_factor, cols*scale_factor, channel] 84 | ''' 85 | x_shape = tf.shape(x) 86 | k = tf.ones([scale_factor, scale_factor, x_shape[-1], x_shape[-1]]) 87 | # note k.shape = [rows, cols, depth_in, depth_output] 88 | output_shape = tf.stack([x_shape[0], x_shape[1] * scale_factor, x_shape[2] * scale_factor, x_shape[-1]]) 89 | upsample = tf.nn.conv2d_transpose(value=x, filter=k, output_shape=output_shape, 90 | strides=[1, scale_factor, scale_factor, 1], 91 | padding='SAME', name=scope) 92 | return upsample 93 | 94 | 95 | # 2D deconvolution 96 | def deconv2d(x, W, stride=2, samefeature=False): 97 | x_shape = tf.shape(x) 98 | if samefeature: 99 | output_shape = tf.stack([x_shape[0], x_shape[1] * stride, x_shape[2] * stride, x_shape[3]]) 100 | else: 101 | output_shape = tf.stack([x_shape[0], x_shape[1] * stride, x_shape[2] * stride, x_shape[3] // stride]) 102 | return tf.nn.conv2d_transpose(x, W, output_shape, strides=[1, stride, stride, 1], padding='SAME') 103 | 104 | 105 | # Unet crop and concat 106 | def crop_and_concat(x1, x2): 107 | x1_shape = tf.shape(x1) 108 | x2_shape = tf.shape(x2) 109 | # offsets for the top left corner of the crop 110 | offsets = [0, (x1_shape[1] - x2_shape[1]) // 2, (x1_shape[2] - x2_shape[2]) // 2, 0] 111 | size = [-1, x2_shape[1], x2_shape[2], -1] 112 | x1_crop = tf.slice(x1, offsets, size) 113 | return tf.concat([x1_crop, x2], 3) 114 | 115 | 116 | # Resnet add 117 | def resnet_Add(x1, x2): 118 | """ 119 | x1 shape[-1] is small x2 shape[-1] 120 | """ 121 | if x1.get_shape().as_list()[3] != x2.get_shape().as_list()[3]: 122 | # Option A:zero-padding 123 | residual_connection = x2 + tf.pad(x1, [[0, 0], [0, 0], [0, 0], 124 | [0, x2.get_shape().as_list()[3] - x1.get_shape().as_list()[3]]]) 125 | else: 126 | residual_connection = x2 + x1 127 | # residual_connection=tf.add(x1,x2) 128 | return residual_connection 129 | -------------------------------------------------------------------------------- /Resnet2d/layer.py: -------------------------------------------------------------------------------- 1 | ''' 2 | covlution layer,pool layer,initialization。。。。 3 | ''' 4 | from __future__ import division 5 | import tensorflow as tf 6 | import numpy as np 7 | 8 | 9 | # Weight initialization (Xavier's init) 10 | def weight_xavier_init(shape, n_inputs, n_outputs, activefunction='sigomd', uniform=True, variable_name=None): 11 | if activefunction == 'sigomd': 12 | if uniform: 13 | init_range = tf.sqrt(6.0 / (n_inputs + n_outputs)) 14 | initial = tf.random_uniform(shape, -init_range, init_range) 15 | return tf.get_variable(name=variable_name, initializer=initial, trainable=True) 16 | else: 17 | stddev = tf.sqrt(2.0 / (n_inputs + n_outputs)) 18 | initial = tf.truncated_normal(shape, mean=0.0, stddev=stddev) 19 | return tf.get_variable(name=variable_name, initializer=initial, trainable=True) 20 | elif activefunction == 'relu': 21 | if uniform: 22 | init_range = tf.sqrt(6.0 / (n_inputs + n_outputs)) * np.sqrt(2) 23 | initial = tf.random_uniform(shape, -init_range, init_range) 24 | return tf.get_variable(name=variable_name, initializer=initial, trainable=True) 25 | else: 26 | stddev = tf.sqrt(2.0 / (n_inputs + n_outputs)) * np.sqrt(2) 27 | initial = tf.truncated_normal(shape, mean=0.0, stddev=stddev) 28 | return tf.get_variable(name=variable_name, initializer=initial, trainable=True) 29 | elif activefunction == 'tan': 30 | if uniform: 31 | init_range = tf.sqrt(6.0 / (n_inputs + n_outputs)) * 4 32 | initial = tf.random_uniform(shape, -init_range, init_range) 33 | return tf.get_variable(name=variable_name, initializer=initial, trainable=True) 34 | else: 35 | stddev = tf.sqrt(2.0 / (n_inputs + n_outputs)) * 4 36 | initial = tf.truncated_normal(shape, mean=0.0, stddev=stddev) 37 | return tf.get_variable(name=variable_name, initializer=initial, trainable=True) 38 | 39 | 40 | # Bias initialization 41 | def bias_variable(shape, variable_name=None): 42 | initial = tf.constant(0.1, shape=shape) 43 | return tf.get_variable(name=variable_name, initializer=initial, trainable=True) 44 | 45 | 46 | # 2D convolution 47 | def conv2d(x, W, stride=1): 48 | conv_2d = tf.nn.conv2d(x, W, strides=[1, stride, stride, 1], padding='SAME') 49 | return conv_2d 50 | 51 | 52 | # Max Pooling 53 | def max_pool2d(x): 54 | pool2d = tf.nn.max_pool(x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME') 55 | return pool2d 56 | 57 | 58 | # Batch Normalization 59 | def normalizationlayer(x, is_train, height=None, width=None, norm_type="group", G=16, esp=1e-5, scope=None): 60 | """ 61 | :param x:input data with shap of[batch,height,width,channel] 62 | :param is_train:flag of normalizationlayer,True is training,False is Testing 63 | :param height:in some condition,the data height is in Runtime determined,such as through deconv layer and conv2d 64 | :param width:in some condition,the data width is in Runtime determined 65 | :param norm_type:normalization type:support"batch","group","None" 66 | :param G:in group normalization,channel is seperated with group number(G) 67 | :param esp:Prevent divisor from being zero 68 | :param scope:normalizationlayer scope 69 | :return: 70 | """ 71 | with tf.name_scope(scope + norm_type): 72 | if norm_type == None: 73 | output = x 74 | elif norm_type == 'batch': 75 | # is_train is True when Training,is False when Testing 76 | output = tf.layers.batch_normalization(x, training=is_train) 77 | elif norm_type == "group": 78 | # tranpose:[bs,h,w,c]to[bs,c,h,w]following the paper 79 | x = tf.transpose(x, [0, 3, 1, 2]) 80 | N, C, H, W = x.get_shape().as_list() 81 | G = min(G, C) 82 | if H == None and W == None: 83 | H, W = height, width 84 | x = tf.reshape(x, [-1, G, C // G, H, W]) 85 | mean, var = tf.nn.moments(x, [2, 3, 4], keep_dims=True) 86 | x = (x - mean) / tf.sqrt(var + esp) 87 | gama = tf.get_variable(scope + norm_type + 'group_gama', [C], initializer=tf.constant_initializer(1.0)) 88 | beta = tf.get_variable(scope + norm_type + 'group_beta', [C], initializer=tf.constant_initializer(0.0)) 89 | gama = tf.reshape(gama, [1, C, 1, 1]) 90 | beta = tf.reshape(beta, [1, C, 1, 1]) 91 | output = tf.reshape(x, [-1, C, H, W]) * gama + beta 92 | # tranpose:[bs,c,h,w]to[bs,h,w,c]following the paper 93 | output = tf.transpose(output, [0, 2, 3, 1]) 94 | return output 95 | 96 | 97 | # resnet add_connect 98 | def resnet_Add(x1, x2): 99 | if x1.get_shape().as_list()[3] != x2.get_shape().as_list()[3]: 100 | # Option A: Zero-padding 101 | residual_connection = x2 + tf.pad(x1, [[0, 0], [0, 0], [0, 0], 102 | [0, x2.get_shape().as_list()[3] - 103 | x1.get_shape().as_list()[3]]]) 104 | else: 105 | residual_connection = x2 + x1 106 | return residual_connection 107 | 108 | 109 | # Convert class labels from scalars to one-hot vectors 110 | # 0 => [1 0 0 0 0 0 0 0 0 0] 111 | # 1 => [0 1 0 0 0 0 0 0 0 0] 112 | # 2 => [0 0 1 0 0 0 0 0 0 0] 113 | def dense_to_one_hot(labels_dense, num_classes): 114 | """ 115 | :param labels_dense: 116 | :param num_classes: 117 | label number must start from zero,such as:0,1,2,3,4,... 118 | :return: 119 | """ 120 | num_labels = labels_dense.shape[0] 121 | labels_one_hot = np.zeros((num_labels, num_classes)) 122 | # method one 123 | for index in range(num_labels): 124 | for classindex in range(num_classes): 125 | if labels_dense[index] == classindex: 126 | labels_one_hot[index, classindex] = 1 127 | # # method two have bug 128 | # index_offset = np.arange(num_labels) * num_classes 129 | # labels_one_hot.flat[index_offset + labels_dense.ravel()] = 1 130 | return labels_one_hot 131 | -------------------------------------------------------------------------------- /TNSCUI2020/Resnet2d/layer.py: -------------------------------------------------------------------------------- 1 | ''' 2 | covlution layer,pool layer,initialization。。。。 3 | ''' 4 | from __future__ import division 5 | import tensorflow as tf 6 | import numpy as np 7 | 8 | 9 | # Weight initialization (Xavier's init) 10 | def weight_xavier_init(shape, n_inputs, n_outputs, activefunction='sigomd', uniform=True, variable_name=None): 11 | if activefunction == 'sigomd': 12 | if uniform: 13 | init_range = tf.sqrt(6.0 / (n_inputs + n_outputs)) 14 | initial = tf.random_uniform(shape, -init_range, init_range) 15 | return tf.get_variable(name=variable_name, initializer=initial, trainable=True) 16 | else: 17 | stddev = tf.sqrt(2.0 / (n_inputs + n_outputs)) 18 | initial = tf.truncated_normal(shape, mean=0.0, stddev=stddev) 19 | return tf.get_variable(name=variable_name, initializer=initial, trainable=True) 20 | elif activefunction == 'relu': 21 | if uniform: 22 | init_range = tf.sqrt(6.0 / (n_inputs + n_outputs)) * np.sqrt(2) 23 | initial = tf.random_uniform(shape, -init_range, init_range) 24 | return tf.get_variable(name=variable_name, initializer=initial, trainable=True) 25 | else: 26 | stddev = tf.sqrt(2.0 / (n_inputs + n_outputs)) * np.sqrt(2) 27 | initial = tf.truncated_normal(shape, mean=0.0, stddev=stddev) 28 | return tf.get_variable(name=variable_name, initializer=initial, trainable=True) 29 | elif activefunction == 'tan': 30 | if uniform: 31 | init_range = tf.sqrt(6.0 / (n_inputs + n_outputs)) * 4 32 | initial = tf.random_uniform(shape, -init_range, init_range) 33 | return tf.get_variable(name=variable_name, initializer=initial, trainable=True) 34 | else: 35 | stddev = tf.sqrt(2.0 / (n_inputs + n_outputs)) * 4 36 | initial = tf.truncated_normal(shape, mean=0.0, stddev=stddev) 37 | return tf.get_variable(name=variable_name, initializer=initial, trainable=True) 38 | 39 | 40 | # Bias initialization 41 | def bias_variable(shape, variable_name=None): 42 | initial = tf.constant(0.1, shape=shape) 43 | return tf.get_variable(name=variable_name, initializer=initial, trainable=True) 44 | 45 | 46 | # 2D convolution 47 | def conv2d(x, W, stride=1): 48 | conv_2d = tf.nn.conv2d(x, W, strides=[1, stride, stride, 1], padding='SAME') 49 | return conv_2d 50 | 51 | 52 | # Max Pooling 53 | def max_pool2d(x): 54 | pool2d = tf.nn.max_pool(x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME') 55 | return pool2d 56 | 57 | 58 | # Batch Normalization 59 | def normalizationlayer(x, is_train, height=None, width=None, norm_type="group", G=16, esp=1e-5, scope=None): 60 | """ 61 | :param x:input data with shap of[batch,height,width,channel] 62 | :param is_train:flag of normalizationlayer,True is training,False is Testing 63 | :param height:in some condition,the data height is in Runtime determined,such as through deconv layer and conv2d 64 | :param width:in some condition,the data width is in Runtime determined 65 | :param norm_type:normalization type:support"batch","group","None" 66 | :param G:in group normalization,channel is seperated with group number(G) 67 | :param esp:Prevent divisor from being zero 68 | :param scope:normalizationlayer scope 69 | :return: 70 | """ 71 | with tf.name_scope(scope + norm_type): 72 | if norm_type == None: 73 | output = x 74 | elif norm_type == 'batch': 75 | # is_train is True when Training,is False when Testing 76 | output = tf.layers.batch_normalization(x, training=is_train) 77 | elif norm_type == "group": 78 | # tranpose:[bs,h,w,c]to[bs,c,h,w]following the paper 79 | x = tf.transpose(x, [0, 3, 1, 2]) 80 | N, C, H, W = x.get_shape().as_list() 81 | G = min(G, C) 82 | if H == None and W == None: 83 | H, W = height, width 84 | x = tf.reshape(x, [-1, G, C // G, H, W]) 85 | mean, var = tf.nn.moments(x, [2, 3, 4], keep_dims=True) 86 | x = (x - mean) / tf.sqrt(var + esp) 87 | gama = tf.get_variable(scope + norm_type + 'group_gama', [C], initializer=tf.constant_initializer(1.0)) 88 | beta = tf.get_variable(scope + norm_type + 'group_beta', [C], initializer=tf.constant_initializer(0.0)) 89 | gama = tf.reshape(gama, [1, C, 1, 1]) 90 | beta = tf.reshape(beta, [1, C, 1, 1]) 91 | output = tf.reshape(x, [-1, C, H, W]) * gama + beta 92 | # tranpose:[bs,c,h,w]to[bs,h,w,c]following the paper 93 | output = tf.transpose(output, [0, 2, 3, 1]) 94 | return output 95 | 96 | 97 | # resnet add_connect 98 | def resnet_Add(x1, x2): 99 | if x1.get_shape().as_list()[3] != x2.get_shape().as_list()[3]: 100 | # Option A: Zero-padding 101 | residual_connection = x2 + tf.pad(x1, [[0, 0], [0, 0], [0, 0], 102 | [0, x2.get_shape().as_list()[3] - 103 | x1.get_shape().as_list()[3]]]) 104 | else: 105 | residual_connection = x2 + x1 106 | return residual_connection 107 | 108 | 109 | # Convert class labels from scalars to one-hot vectors 110 | # 0 => [1 0 0 0 0 0 0 0 0 0] 111 | # 1 => [0 1 0 0 0 0 0 0 0 0] 112 | # 2 => [0 0 1 0 0 0 0 0 0 0] 113 | def dense_to_one_hot(labels_dense, num_classes): 114 | """ 115 | :param labels_dense: 116 | :param num_classes: 117 | label number must start from zero,such as:0,1,2,3,4,... 118 | :return: 119 | """ 120 | num_labels = labels_dense.shape[0] 121 | labels_one_hot = np.zeros((num_labels, num_classes)) 122 | # method one 123 | for index in range(num_labels): 124 | for classindex in range(num_classes): 125 | if labels_dense[index] == classindex: 126 | labels_one_hot[index, classindex] = 1 127 | # # method two have bug 128 | # index_offset = np.arange(num_labels) * num_classes 129 | # labels_one_hot.flat[index_offset + labels_dense.ravel()] = 1 130 | return labels_one_hot 131 | -------------------------------------------------------------------------------- /TNSCUI2020/dataprocess/Augmentation/ImageAugmentation.py: -------------------------------------------------------------------------------- 1 | from dataprocess.Augmentation.images_masks_transform import ImageDataGenerator 2 | import cv2 3 | import pandas as pd 4 | import os 5 | 6 | ''' 7 | Feature Standardization 8 | standardize pixel values across the entire dataset 9 | ZCA Whitening 10 | A whitening transform of an image is a linear algebra operation that reduces the redundancy in the matrix of pixel images. 11 | Less redundancy in the image is intended to better highlight the structures and features in the image to the learning algorithm. 12 | Typically, image whitening is performed using the Principal Component Analysis (PCA) technique. 13 | More recently, an alternative called ZCA (learn more in Appendix A of this tech report) shows better results and results in 14 | transformed images that keeps all of the original dimensions and unlike PCA, resulting transformed images still look like their originals. 15 | Random Rotations 16 | sample data may have varying and different rotations in the scene. 17 | Random Shifts 18 | images may not be centered in the frame. They may be off-center in a variety of different ways. 19 | RESCALE 20 | 对图像按照指定的尺度因子, 进行放大或缩小, 设置值在0- 1之间,通常为1 / 255; 21 | Random Flips 22 | improve performance on large and complex problems is to create random flips of images in your training data. 23 | fill_mode: 填充像素, 出现在旋转或平移之后. 24 | ''' 25 | 26 | 27 | class DataAug(object): 28 | ''' 29 | transform Image and Mask together 30 | ''' 31 | 32 | def __init__(self, rotation=5, width_shift=0.05, 33 | height_shift=0.05, rescale=1.2, horizontal_flip=True, vertical_flip=False): 34 | # define data preparation 35 | self.__datagen = ImageDataGenerator(featurewise_center=False, featurewise_std_normalization=False, 36 | zca_whitening=False, 37 | rotation_range=rotation, width_shift_range=width_shift, 38 | height_shift_range=height_shift, rescale=rescale, 39 | horizontal_flip=horizontal_flip, vertical_flip=vertical_flip, 40 | fill_mode='nearest') 41 | 42 | def __ImageMaskTranform(self, images, labels, index, number, path): 43 | # reshape to be [samples][pixels][width][height][channels] 44 | images = cv2.imread(images, 0) 45 | labels = cv2.imread(labels, 0) 46 | if len(images.shape) == 2: 47 | srcimage = images.reshape([1, images.shape[0], images.shape[1], 1]) 48 | srclabel = labels.reshape([1, labels.shape[0], labels.shape[1], 1]) 49 | else: 50 | srcimage = images.reshape([1, images.shape[0], images.shape[1], images.shape[2]]) 51 | srclabel = labels.reshape([1, labels.shape[0], labels.shape[1], labels.shape[2]]) 52 | 53 | i = 0 54 | for batch1, batch2 in self.__datagen.flow(srcimage, srclabel): 55 | i += 1 56 | batch1 = batch1[0] 57 | src_path = path + 'image\\' 58 | if not os.path.exists(src_path): 59 | os.makedirs(src_path) 60 | cv2.imwrite(src_path + str(index) + '_' + str(i) + '.bmp', batch1) 61 | 62 | batch2 = batch2[0] 63 | mask_path = path + 'mask\\' 64 | if not os.path.exists(mask_path): 65 | os.makedirs(mask_path) 66 | cv2.imwrite(mask_path + str(index) + '_' + str(i) + '.bmp', batch2) 67 | 68 | if i > number - 1: 69 | break 70 | 71 | def DataAugmentation(self, filepathX, number=100, path=None): 72 | csvdata = pd.read_csv(filepathX) 73 | dataX = csvdata.icol(0).values 74 | dataY = csvdata.icol(1).values 75 | for index in range(dataX.shape[0]): 76 | # For images 77 | images = dataX[index] 78 | # For labels 79 | labels = dataY[index] 80 | self.__ImageMaskTranform(images, labels, index, number, path) 81 | 82 | 83 | class DataAugClassify(object): 84 | ''' 85 | transform Image and Mask together 86 | ''' 87 | 88 | def __init__(self, rotation=5, width_shift=0.05, 89 | height_shift=0.05, rescale=1.2, horizontal_flip=True, vertical_flip=False): 90 | # define data preparation 91 | self.__datagen = ImageDataGenerator(featurewise_center=False, featurewise_std_normalization=False, 92 | zca_whitening=False, 93 | rotation_range=rotation, width_shift_range=width_shift, 94 | height_shift_range=height_shift, rescale=rescale, 95 | horizontal_flip=horizontal_flip, vertical_flip=vertical_flip, 96 | fill_mode='nearest') 97 | 98 | def __ImageMaskTranform(self, images, labels, index, number, path): 99 | # reshape to be [samples][pixels][width][height][channels] 100 | images = cv2.imread(images, 0) 101 | if len(images.shape) == 2: 102 | srcimage = images.reshape([1, images.shape[0], images.shape[1], 1]) 103 | else: 104 | srcimage = images.reshape([1, images.shape[0], images.shape[1], images.shape[2]]) 105 | 106 | i = 0 107 | for batch1, _ in self.__datagen.flow(srcimage, srcimage): 108 | i += 1 109 | batch1 = batch1[0] 110 | src_path = path + str(labels) + '\\' 111 | if not os.path.exists(src_path): 112 | os.makedirs(src_path) 113 | cv2.imwrite(src_path + str(index) + '_' + str(i) + '.bmp', batch1) 114 | if i > number - 1: 115 | break 116 | 117 | def DataAugmentation(self, filepathX, number=100, path=None): 118 | csvdata = pd.read_csv(filepathX) 119 | dataX = csvdata.icol(1).values 120 | dataY = csvdata.icol(0).values 121 | for index in range(dataX.shape[0]): 122 | # For images 123 | images = dataX[index] 124 | # For labels 125 | labels = dataY[index] 126 | self.__ImageMaskTranform(images, labels, index, number, path) 127 | -------------------------------------------------------------------------------- /Vnet2d/layer.py: -------------------------------------------------------------------------------- 1 | ''' 2 | covlution layer,pool layer,initialization。。。。 3 | ''' 4 | from __future__ import division 5 | import tensorflow as tf 6 | import numpy as np 7 | 8 | 9 | # Weight initialization (Xavier's init) 10 | def weight_xavier_init(shape, n_inputs, n_outputs, activefunction='sigomd', uniform=True, variable_name=None): 11 | if activefunction == 'sigomd': 12 | if uniform: 13 | init_range = tf.sqrt(6.0 / (n_inputs + n_outputs)) 14 | initial = tf.random_uniform(shape, -init_range, init_range) 15 | return tf.get_variable(name=variable_name, initializer=initial, trainable=True) 16 | else: 17 | stddev = tf.sqrt(2.0 / (n_inputs + n_outputs)) 18 | initial = tf.truncated_normal(shape, mean=0.0, stddev=stddev) 19 | return tf.get_variable(name=variable_name, initializer=initial, trainable=True) 20 | elif activefunction == 'relu': 21 | if uniform: 22 | init_range = tf.sqrt(6.0 / (n_inputs + n_outputs)) * np.sqrt(2) 23 | initial = tf.random_uniform(shape, -init_range, init_range) 24 | return tf.get_variable(name=variable_name, initializer=initial, trainable=True) 25 | else: 26 | stddev = tf.sqrt(2.0 / (n_inputs + n_outputs)) * np.sqrt(2) 27 | initial = tf.truncated_normal(shape, mean=0.0, stddev=stddev) 28 | return tf.get_variable(name=variable_name, initializer=initial, trainable=True) 29 | elif activefunction == 'tan': 30 | if uniform: 31 | init_range = tf.sqrt(6.0 / (n_inputs + n_outputs)) * 4 32 | initial = tf.random_uniform(shape, -init_range, init_range) 33 | return tf.get_variable(name=variable_name, initializer=initial, trainable=True) 34 | else: 35 | stddev = tf.sqrt(2.0 / (n_inputs + n_outputs)) * 4 36 | initial = tf.truncated_normal(shape, mean=0.0, stddev=stddev) 37 | return tf.get_variable(name=variable_name, initializer=initial, trainable=True) 38 | 39 | 40 | # Bias initialization 41 | def bias_variable(shape, variable_name=None): 42 | initial = tf.constant(0.1, shape=shape) 43 | return tf.get_variable(name=variable_name, initializer=initial, trainable=True) 44 | 45 | 46 | # 2D convolution 47 | def conv2d(x, W, strides=1): 48 | conv_2d = tf.nn.conv2d(x, W, strides=[1, strides, strides, 1], padding='SAME') 49 | return conv_2d 50 | 51 | 52 | def normalizationlayer(x, is_train, height=None, width=None, norm_type='None', G=16, esp=1e-5, scope=None): 53 | with tf.name_scope(scope + norm_type): 54 | if norm_type == 'None': 55 | output = x 56 | elif norm_type == 'batch': 57 | output = tf.contrib.layers.batch_norm(x, center=True, scale=True, is_training=is_train) 58 | elif norm_type == 'group': 59 | # tranpose:[bs,h,w,c]to[bs,c,h,w]follwing the paper 60 | x = tf.transpose(x, [0, 3, 1, 2]) 61 | N, C, H, W = x.get_shape().as_list() 62 | G = min(G, C) 63 | if H == None and W == None: 64 | H, W = height, width 65 | x = tf.reshape(x, [-1, G, C // G, H, W]) 66 | mean, var = tf.nn.moments(x, [2, 3, 4], keep_dims=True) 67 | x = (x - mean) / tf.sqrt(var + esp) 68 | # per channel gama and beta 69 | gama = tf.get_variable(scope + norm_type + 'group_gama', [C], initializer=tf.constant_initializer(1.0)) 70 | beta = tf.get_variable(scope + norm_type + 'group_beta', [C], initializer=tf.constant_initializer(0.0)) 71 | gama = tf.reshape(gama, [1, C, 1, 1]) 72 | beta = tf.reshape(beta, [1, C, 1, 1]) 73 | output = tf.reshape(x, [-1, C, H, W]) * gama + beta 74 | # tranpose:[bs,c,h,w]to[bs,h,w,c]follwing the paper 75 | output = tf.transpose(output, [0, 2, 3, 1]) 76 | return output 77 | 78 | 79 | # 2D upsampling 80 | def upsample2d(x, scale_factor, scope=None): 81 | '''' 82 | X shape is [nsample,rows, cols, channel] 83 | out shape is[nsample,rows*scale_factor, cols*scale_factor, channel] 84 | ''' 85 | x_shape = tf.shape(x) 86 | k = tf.ones([scale_factor, scale_factor, x_shape[-1], x_shape[-1]]) 87 | # note k.shape = [rows, cols, depth_in, depth_output] 88 | output_shape = tf.stack([x_shape[0], x_shape[1] * scale_factor, x_shape[2] * scale_factor, x_shape[-1]]) 89 | upsample = tf.nn.conv2d_transpose(value=x, filter=k, output_shape=output_shape, 90 | strides=[1, scale_factor, scale_factor, 1], 91 | padding='SAME', name=scope) 92 | return upsample 93 | 94 | 95 | # 2D deconvolution 96 | def deconv2d(x, W, stride=2, samefeature=False): 97 | x_shape = tf.shape(x) 98 | if samefeature: 99 | output_shape = tf.stack([x_shape[0], x_shape[1] * stride, x_shape[2] * stride, x_shape[3]]) 100 | else: 101 | output_shape = tf.stack([x_shape[0], x_shape[1] * stride, x_shape[2] * stride, x_shape[3] // stride]) 102 | return tf.nn.conv2d_transpose(x, W, output_shape, strides=[1, stride, stride, 1], padding='SAME') 103 | 104 | 105 | # Unet crop and concat 106 | def crop_and_concat(x1, x2): 107 | x1_shape = tf.shape(x1) 108 | x2_shape = tf.shape(x2) 109 | # offsets for the top left corner of the crop 110 | offsets = [0, (x1_shape[1] - x2_shape[1]) // 2, (x1_shape[2] - x2_shape[2]) // 2, 0] 111 | size = [-1, x2_shape[1], x2_shape[2], -1] 112 | x1_crop = tf.slice(x1, offsets, size) 113 | return tf.concat([x1_crop, x2], 3) 114 | 115 | 116 | # Resnet add 117 | def resnet_Add(x1, x2): 118 | """ 119 | x1 shape[-1] is small x2 shape[-1] 120 | """ 121 | if x1.get_shape().as_list()[3] != x2.get_shape().as_list()[3]: 122 | # Option A:zero-padding 123 | residual_connection = x2 + tf.pad(x1, [[0, 0], [0, 0], [0, 0], 124 | [0, x2.get_shape().as_list()[3] - x1.get_shape().as_list()[3]]]) 125 | else: 126 | residual_connection = x2 + x1 127 | # residual_connection=tf.add(x1,x2) 128 | return residual_connection 129 | 130 | 131 | # Convert class labels from scalars to one-hot vectors 132 | # 0 => [1 0 0 0 0 0 0 0 0 0] 133 | # 1 => [0 1 0 0 0 0 0 0 0 0] 134 | # 2 => [0 0 1 0 0 0 0 0 0 0] 135 | def dense_to_one_hot(labels_dense, num_classes): 136 | """ 137 | :param labels_dense: 138 | :param num_classes: 139 | label number must start from zero,such as:0,1,2,3,4,... 140 | :return: 141 | """ 142 | num_labels = labels_dense.shape[0] 143 | labels_one_hot = np.zeros((num_labels, num_classes)) 144 | # method one 145 | for index in range(num_labels): 146 | for classindex in range(num_classes): 147 | if labels_dense[index] == classindex: 148 | labels_one_hot[index, classindex] = 1 149 | # # method two have bug 150 | # index_offset = np.arange(num_labels) * num_classes 151 | # labels_one_hot.flat[index_offset + labels_dense.ravel()] = 1 152 | return labels_one_hot -------------------------------------------------------------------------------- /Resnet2d/model_resNet2d.py: -------------------------------------------------------------------------------- 1 | ''' 2 | 3 | ''' 4 | from Resnet2d.layer import (conv2d, normalizationlayer, max_pool2d, resnet_Add, weight_xavier_init, bias_variable, 5 | dense_to_one_hot) 6 | import tensorflow as tf 7 | import numpy as np 8 | import cv2 9 | import os 10 | 11 | 12 | def conv_relu_drop(x, kernal, drop, phase, height=None, width=None, scope=None): 13 | with tf.name_scope(scope): 14 | W = weight_xavier_init(shape=kernal, n_inputs=kernal[0] * kernal[1] * kernal[2], 15 | n_outputs=kernal[-1], activefunction='relu', variable_name=scope + 'conv_W') 16 | B = bias_variable([kernal[-1]], variable_name=scope + 'conv_B') 17 | conv = conv2d(x, W) + B 18 | conv = normalizationlayer(conv, is_train=phase, height=height, width=width, norm_type='group', scope=scope) 19 | conv = tf.nn.dropout(tf.nn.relu(conv), drop) 20 | return conv 21 | 22 | 23 | def full_connected_relu_drop(x, kernal, drop, activefunction='relu', scope=None): 24 | with tf.name_scope(scope): 25 | W = weight_xavier_init(shape=kernal, n_inputs=kernal[0] * kernal[1], 26 | n_outputs=kernal[-1], activefunction='relu', variable_name=scope + 'W') 27 | B = bias_variable([kernal[-1]], variable_name=scope + 'B') 28 | FC = tf.matmul(x, W) + B 29 | if activefunction == 'relu': 30 | FC = tf.nn.relu(FC) 31 | FC = tf.nn.dropout(FC, drop) 32 | elif activefunction == 'softmax': 33 | FC = tf.nn.softmax(FC) 34 | return FC 35 | 36 | 37 | def _create_conv_net(X, image_width, image_height, image_channel, drop, phase, n_class=1): 38 | inputX = tf.reshape(X, [-1, image_width, image_height, image_channel]) # shape=(?, 32, 32, 1) 39 | # Vnet model 40 | # layer1->convolution 41 | layer0 = conv_relu_drop(x=inputX, kernal=(3, 3, image_channel, 16), drop=drop, phase=phase, scope='layer0') 42 | layer1 = conv_relu_drop(x=layer0, kernal=(3, 3, 16, 16), drop=drop, phase=phase, scope='layer1') 43 | layer1 = resnet_Add(x1=layer0, x2=layer1) 44 | # down sampling1 45 | down1 = max_pool2d(x=layer1) 46 | # layer2->convolution 47 | layer2 = conv_relu_drop(x=down1, kernal=(3, 3, 16, 32), drop=drop, phase=phase, scope='layer2_1') 48 | layer2 = conv_relu_drop(x=layer2, kernal=(3, 3, 32, 32), drop=drop, phase=phase, scope='layer2_2') 49 | layer2 = resnet_Add(x1=down1, x2=layer2) 50 | # down sampling2 51 | down2 = max_pool2d(x=layer2) 52 | # layer3->convolution 53 | layer3 = conv_relu_drop(x=down2, kernal=(3, 3, 32, 64), drop=drop, phase=phase, scope='layer3_1') 54 | layer3 = conv_relu_drop(x=layer3, kernal=(3, 3, 64, 64), drop=drop, phase=phase, scope='layer3_2') 55 | layer3 = resnet_Add(x1=down2, x2=layer3) 56 | # down sampling3 57 | down3 = max_pool2d(x=layer3) 58 | # layer4->convolution 59 | layer4 = conv_relu_drop(x=down3, kernal=(3, 3, 64, 128), drop=drop, phase=phase, scope='layer4_1') 60 | layer4 = conv_relu_drop(x=layer4, kernal=(3, 3, 128, 128), drop=drop, phase=phase, scope='layer4_2') 61 | layer4 = resnet_Add(x1=down3, x2=layer4) 62 | # down sampling4 63 | down4 = max_pool2d(x=layer4) 64 | # layer5->convolution 65 | layer5 = conv_relu_drop(x=down4, kernal=(3, 3, 128, 256), drop=drop, phase=phase, scope='layer5_1') 66 | layer5 = conv_relu_drop(x=layer5, kernal=(3, 3, 256, 256), drop=drop, phase=phase, scope='layer5_2') 67 | layer5 = resnet_Add(x1=down4, x2=layer5) 68 | # down sampling5 69 | down5 = max_pool2d(x=layer5) 70 | # layer6->convolution 71 | layer6 = conv_relu_drop(x=down5, kernal=(3, 3, 256, 512), drop=drop, phase=phase, scope='layer6_1') 72 | layer6 = conv_relu_drop(x=layer6, kernal=(3, 3, 512, 512), drop=drop, phase=phase, scope='layer6_2') 73 | layer6 = resnet_Add(x1=down5, x2=layer6) 74 | # down sampling5 75 | down6 = max_pool2d(x=layer6) 76 | 77 | gap = tf.reduce_mean(down6, axis=(1, 2)) 78 | # layer7->FC1 79 | layer7 = tf.reshape(gap, [-1, 512]) # shape=(?, 512) 80 | layer7 = full_connected_relu_drop(x=layer7, kernal=(512, 512), drop=drop, activefunction='relu', 81 | scope='fc1') 82 | # layer7->output 83 | output = full_connected_relu_drop(x=layer7, kernal=(512, n_class), drop=drop, activefunction='regression', 84 | scope='output') 85 | return output 86 | 87 | 88 | # Serve data by batches 89 | def _next_batch(train_images, train_labels, batch_size, index_in_epoch): 90 | start = index_in_epoch 91 | index_in_epoch += batch_size 92 | 93 | num_examples = train_images.shape[0] 94 | # when all trainig data have been already used, it is reorder randomly 95 | if index_in_epoch > num_examples: 96 | # shuffle the data 97 | perm = np.arange(num_examples) 98 | np.random.shuffle(perm) 99 | train_images = train_images[perm] 100 | train_labels = train_labels[perm] 101 | # start next epoch 102 | start = 0 103 | index_in_epoch = batch_size 104 | assert batch_size <= num_examples 105 | end = index_in_epoch 106 | return train_images[start:end], train_labels[start:end], index_in_epoch 107 | 108 | 109 | class ResNet2dModule(object): 110 | """ 111 | A ResNet2d implementation 112 | :param image_height: number of height in the input image 113 | :param image_width: number of width in the input image 114 | :param image_depth: number of depth in the input image 115 | :param channels: number of channels in the input image 116 | :param costname: name of the cost function.Default is "dice coefficient" 117 | """ 118 | 119 | def __init__(self, image_height, image_width, channels=1, n_class=2, costname="cross_entropy", 120 | inference=False, model_path=None): 121 | self.image_width = image_width 122 | self.image_height = image_height 123 | self.channels = channels 124 | self.n_class = n_class 125 | 126 | self.X = tf.placeholder("float", shape=[None, self.image_height, self.image_width, self.channels]) 127 | self.Y_gt = tf.placeholder("float", shape=[None, self.n_class]) 128 | self.lr = tf.placeholder('float') 129 | self.phase = tf.placeholder(tf.bool) 130 | self.drop = tf.placeholder('float') 131 | self.alpha = [1, 1] 132 | self.gamma = 4 133 | self.Y_pred_logits = _create_conv_net(self.X, self.image_width, self.image_height, self.channels, self.drop, 134 | self.phase, n_class=n_class) 135 | 136 | self.Y_pred = tf.nn.softmax(self.Y_pred_logits) 137 | if costname == "focal_loss": 138 | self.cost = self.__get_cost(costname, self.Y_pred) 139 | else: 140 | self.cost = self.__get_cost(costname, self.Y_pred_logits) 141 | self.predict = tf.argmax(self.Y_pred, 1) 142 | self.accuracy = self.__get_accuracy(self.Y_pred) 143 | if inference: 144 | init = tf.global_variables_initializer() 145 | saver = tf.train.Saver() 146 | self.sess = tf.InteractiveSession() 147 | self.sess.run(init) 148 | saver.restore(self.sess, model_path) 149 | else: 150 | self.sess = tf.InteractiveSession( 151 | config=tf.ConfigProto(allow_soft_placement=True, log_device_placement=False)) 152 | 153 | def __get_cost(self, cost_name, Y_pred): 154 | if cost_name == "cross_entropy": 155 | # the function first calculate softmax then calculate the 156 | # cross_entropy(-tf.reduce_sum(self.Y_gt*tf.log(Y_pred))), 157 | # logits don't through the tf.nn,softmax function 158 | cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=self.Y_gt, logits=Y_pred)) 159 | return cost 160 | if cost_name == "focal_loss": 161 | weight_loss = np.array(self.alpha) 162 | epsilon = 1.e-5 163 | # Scale predictions so that the class probas of each sample sum to 1 164 | output = Y_pred / tf.reduce_sum(Y_pred, axis=- 1, keepdims=True) 165 | # Clip the prediction value to prevent NaN's and Inf's 166 | output = tf.clip_by_value(output, epsilon, 1. - epsilon) 167 | # Calculate Cross Entropy 168 | cross_entropy = -self.Y_gt * tf.log(output) 169 | # Calculate Focal Loss 170 | loss = tf.pow(1 - output, self.gamma) * cross_entropy 171 | loss = tf.reduce_mean(loss, axis=0) 172 | loss = tf.reduce_mean(weight_loss * loss) 173 | return loss 174 | 175 | def __get_accuracy(self, Y_pred): 176 | correct_predict = tf.equal(tf.argmax(Y_pred, 1), tf.argmax(self.Y_gt, 1)) 177 | accuracy = tf.reduce_mean(tf.cast(correct_predict, 'float')) 178 | return accuracy 179 | 180 | def train(self, train_images, train_lanbels, model_path, logs_path, learning_rate, dropout_conv=0.8, train_epochs=5, 181 | batch_size=1): 182 | label_counts = np.unique(train_lanbels).shape[0] 183 | if not os.path.exists(logs_path): 184 | os.makedirs(logs_path) 185 | if not os.path.exists(logs_path + "model\\"): 186 | os.makedirs(logs_path + "model\\") 187 | model_path = logs_path + "model\\" + model_path 188 | # update the moving average of batch norm before finish the training step 189 | update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS) 190 | with tf.control_dependencies(update_ops): 191 | # ensures that we execute the update_ops before performing the train_step 192 | train_op = tf.train.AdamOptimizer(self.lr).minimize(self.cost) 193 | 194 | init = tf.global_variables_initializer() 195 | saver = tf.train.Saver(tf.all_variables(), max_to_keep=10) 196 | 197 | tf.summary.scalar("loss", self.cost) 198 | tf.summary.scalar("accuracy", self.accuracy) 199 | merged_summary_op = tf.summary.merge_all() 200 | 201 | summary_writer = tf.summary.FileWriter(logs_path, graph=tf.get_default_graph()) 202 | self.sess.run(init) 203 | 204 | DISPLAY_STEP = 1 205 | index_in_epoch = 0 206 | 207 | train_epochs = train_images.shape[0] * train_epochs 208 | for i in range(train_epochs): 209 | # get new batch 210 | batch_xs_path, batch_ys_path, index_in_epoch = _next_batch(train_images, train_lanbels, batch_size, 211 | index_in_epoch) 212 | # label one_hot coding 213 | train_labels_onehot = dense_to_one_hot(batch_ys_path, label_counts) 214 | batch_ys = train_labels_onehot.astype(np.float) 215 | train_images_data = np.empty((len(batch_xs_path), self.image_height, self.image_width, self.channels)) 216 | for num in range(len(batch_xs_path)): 217 | train_image = cv2.imread(batch_xs_path[num], 0) 218 | train_image = cv2.resize(train_image, (self.image_height, self.image_width)) 219 | batchimage = np.reshape(train_image, (self.image_height, self.image_width, self.channels)) 220 | train_images_data[num, :, :, :] = batchimage 221 | train_images_data = train_images_data.astype(np.float) 222 | # Normalize from [0:255] => [0.0:1.0] 223 | batch_xs = np.multiply(train_images_data, 1.0 / 255.0) 224 | # Extracting images and labels from given data 225 | batch_xs = batch_xs.astype(np.float) 226 | batch_ys = batch_ys.astype(np.float) 227 | # check progress on every 1st,2nd,...,10th,20th,...,100th... step 228 | if i % DISPLAY_STEP == 0 or (i + 1) == train_epochs: 229 | train_loss, train_accuracy = self.sess.run([self.cost, self.accuracy], 230 | feed_dict={self.X: batch_xs, 231 | self.Y_gt: batch_ys, 232 | self.lr: learning_rate, 233 | self.drop: 1, 234 | self.phase: 1}) 235 | print('epochs %d training_loss ,training_accuracy=> %.5f,%.5f ' % (i, train_loss, train_accuracy)) 236 | save_path = saver.save(self.sess, model_path, global_step=i) 237 | print("Model saved in file:", save_path) 238 | if i % (DISPLAY_STEP * 10) == 0 and i: 239 | DISPLAY_STEP *= 10 240 | 241 | # train on batch 242 | _, summary = self.sess.run([train_op, merged_summary_op], feed_dict={self.X: batch_xs, 243 | self.Y_gt: batch_ys, 244 | self.lr: learning_rate, 245 | self.drop: dropout_conv, 246 | self.phase: 1}) 247 | summary_writer.add_summary(summary, i) 248 | summary_writer.close() 249 | 250 | save_path = saver.save(self.sess, model_path) 251 | print("Model saved in file:", save_path) 252 | self.sess.close() 253 | 254 | def prediction(self, test_images): 255 | test_images = np.reshape(test_images, (1, test_images.shape[0], test_images.shape[1], 1)) 256 | predictvalue = np.zeros(test_images.shape[0]) 257 | predict_probvalue = np.zeros(test_images.shape[0], np.float) 258 | y_dummy = np.empty((test_images.shape[0], self.n_class)) 259 | for i in range(test_images.shape[0]): 260 | predictvaluetmp, predict_probvaluetmp = self.sess.run([self.predict, self.Y_pred], 261 | feed_dict={self.X: [test_images[i]], 262 | self.Y_gt: y_dummy, 263 | self.drop: 1, 264 | self.phase: 1}) 265 | predictvalue[i], predict_probvalue[i] = predictvaluetmp, predict_probvaluetmp[0][1] 266 | return predictvalue, predict_probvalue 267 | -------------------------------------------------------------------------------- /TNSCUI2020/Resnet2d/model_resNet2d.py: -------------------------------------------------------------------------------- 1 | ''' 2 | 3 | ''' 4 | from Resnet2d.layer import (conv2d, normalizationlayer, max_pool2d, resnet_Add, weight_xavier_init, bias_variable, 5 | dense_to_one_hot) 6 | import tensorflow as tf 7 | import numpy as np 8 | import cv2 9 | import os 10 | 11 | 12 | def conv_relu_drop(x, kernal, drop, phase, height=None, width=None, scope=None): 13 | with tf.name_scope(scope): 14 | W = weight_xavier_init(shape=kernal, n_inputs=kernal[0] * kernal[1] * kernal[2], 15 | n_outputs=kernal[-1], activefunction='relu', variable_name=scope + 'conv_W') 16 | B = bias_variable([kernal[-1]], variable_name=scope + 'conv_B') 17 | conv = conv2d(x, W) + B 18 | conv = normalizationlayer(conv, is_train=phase, height=height, width=width, norm_type='group', scope=scope) 19 | conv = tf.nn.dropout(tf.nn.relu(conv), drop) 20 | return conv 21 | 22 | 23 | def full_connected_relu_drop(x, kernal, drop, activefunction='relu', scope=None): 24 | with tf.name_scope(scope): 25 | W = weight_xavier_init(shape=kernal, n_inputs=kernal[0] * kernal[1], 26 | n_outputs=kernal[-1], activefunction='relu', variable_name=scope + 'W') 27 | B = bias_variable([kernal[-1]], variable_name=scope + 'B') 28 | FC = tf.matmul(x, W) + B 29 | if activefunction == 'relu': 30 | FC = tf.nn.relu(FC) 31 | FC = tf.nn.dropout(FC, drop) 32 | elif activefunction == 'softmax': 33 | FC = tf.nn.softmax(FC) 34 | return FC 35 | 36 | 37 | def _create_conv_net(X, image_width, image_height, image_channel, drop, phase, n_class=1): 38 | inputX = tf.reshape(X, [-1, image_width, image_height, image_channel]) # shape=(?, 32, 32, 1) 39 | # Vnet model 40 | # layer1->convolution 41 | layer0 = conv_relu_drop(x=inputX, kernal=(3, 3, image_channel, 16), drop=drop, phase=phase, scope='layer0') 42 | layer1 = conv_relu_drop(x=layer0, kernal=(3, 3, 16, 16), drop=drop, phase=phase, scope='layer1') 43 | layer1 = resnet_Add(x1=layer0, x2=layer1) 44 | # down sampling1 45 | down1 = max_pool2d(x=layer1) 46 | # layer2->convolution 47 | layer2 = conv_relu_drop(x=down1, kernal=(3, 3, 16, 32), drop=drop, phase=phase, scope='layer2_1') 48 | layer2 = conv_relu_drop(x=layer2, kernal=(3, 3, 32, 32), drop=drop, phase=phase, scope='layer2_2') 49 | layer2 = resnet_Add(x1=down1, x2=layer2) 50 | # down sampling2 51 | down2 = max_pool2d(x=layer2) 52 | # layer3->convolution 53 | layer3 = conv_relu_drop(x=down2, kernal=(3, 3, 32, 64), drop=drop, phase=phase, scope='layer3_1') 54 | layer3 = conv_relu_drop(x=layer3, kernal=(3, 3, 64, 64), drop=drop, phase=phase, scope='layer3_2') 55 | layer3 = resnet_Add(x1=down2, x2=layer3) 56 | # down sampling3 57 | down3 = max_pool2d(x=layer3) 58 | # layer4->convolution 59 | layer4 = conv_relu_drop(x=down3, kernal=(3, 3, 64, 128), drop=drop, phase=phase, scope='layer4_1') 60 | layer4 = conv_relu_drop(x=layer4, kernal=(3, 3, 128, 128), drop=drop, phase=phase, scope='layer4_2') 61 | layer4 = resnet_Add(x1=down3, x2=layer4) 62 | # down sampling4 63 | down4 = max_pool2d(x=layer4) 64 | # layer5->convolution 65 | layer5 = conv_relu_drop(x=down4, kernal=(3, 3, 128, 256), drop=drop, phase=phase, scope='layer5_1') 66 | layer5 = conv_relu_drop(x=layer5, kernal=(3, 3, 256, 256), drop=drop, phase=phase, scope='layer5_2') 67 | layer5 = resnet_Add(x1=down4, x2=layer5) 68 | # down sampling5 69 | down5 = max_pool2d(x=layer5) 70 | # layer6->convolution 71 | layer6 = conv_relu_drop(x=down5, kernal=(3, 3, 256, 512), drop=drop, phase=phase, scope='layer6_1') 72 | layer6 = conv_relu_drop(x=layer6, kernal=(3, 3, 512, 512), drop=drop, phase=phase, scope='layer6_2') 73 | layer6 = resnet_Add(x1=down5, x2=layer6) 74 | # down sampling5 75 | down6 = max_pool2d(x=layer6) 76 | 77 | gap = tf.reduce_mean(down6, axis=(1, 2)) 78 | # layer7->FC1 79 | layer7 = tf.reshape(gap, [-1, 512]) # shape=(?, 512) 80 | layer7 = full_connected_relu_drop(x=layer7, kernal=(512, 512), drop=drop, activefunction='relu', 81 | scope='fc1') 82 | # layer7->output 83 | output = full_connected_relu_drop(x=layer7, kernal=(512, n_class), drop=drop, activefunction='regression', 84 | scope='output') 85 | return output 86 | 87 | 88 | # Serve data by batches 89 | def _next_batch(train_images, train_labels, batch_size, index_in_epoch): 90 | start = index_in_epoch 91 | index_in_epoch += batch_size 92 | 93 | num_examples = train_images.shape[0] 94 | # when all trainig data have been already used, it is reorder randomly 95 | if index_in_epoch > num_examples: 96 | # shuffle the data 97 | perm = np.arange(num_examples) 98 | np.random.shuffle(perm) 99 | train_images = train_images[perm] 100 | train_labels = train_labels[perm] 101 | # start next epoch 102 | start = 0 103 | index_in_epoch = batch_size 104 | assert batch_size <= num_examples 105 | end = index_in_epoch 106 | return train_images[start:end], train_labels[start:end], index_in_epoch 107 | 108 | 109 | class ResNet2dModule(object): 110 | """ 111 | A ResNet2d implementation 112 | :param image_height: number of height in the input image 113 | :param image_width: number of width in the input image 114 | :param image_depth: number of depth in the input image 115 | :param channels: number of channels in the input image 116 | :param costname: name of the cost function.Default is "dice coefficient" 117 | """ 118 | 119 | def __init__(self, image_height, image_width, channels=1, n_class=2, costname="cross_entropy", 120 | inference=False, model_path=None): 121 | self.image_width = image_width 122 | self.image_height = image_height 123 | self.channels = channels 124 | self.n_class = n_class 125 | 126 | self.X = tf.placeholder("float", shape=[None, self.image_height, self.image_width, self.channels]) 127 | self.Y_gt = tf.placeholder("float", shape=[None, self.n_class]) 128 | self.lr = tf.placeholder('float') 129 | self.phase = tf.placeholder(tf.bool) 130 | self.drop = tf.placeholder('float') 131 | self.alpha = [1, 1] 132 | self.gamma = 4 133 | self.Y_pred_logits = _create_conv_net(self.X, self.image_width, self.image_height, self.channels, self.drop, 134 | self.phase, n_class=n_class) 135 | 136 | self.Y_pred = tf.nn.softmax(self.Y_pred_logits) 137 | if costname == "focal_loss": 138 | self.cost = self.__get_cost(costname, self.Y_pred) 139 | else: 140 | self.cost = self.__get_cost(costname, self.Y_pred_logits) 141 | self.predict = tf.argmax(self.Y_pred, 1) 142 | self.accuracy = self.__get_accuracy(self.Y_pred) 143 | if inference: 144 | init = tf.global_variables_initializer() 145 | saver = tf.train.Saver() 146 | self.sess = tf.InteractiveSession() 147 | self.sess.run(init) 148 | saver.restore(self.sess, model_path) 149 | else: 150 | self.sess = tf.InteractiveSession( 151 | config=tf.ConfigProto(allow_soft_placement=True, log_device_placement=False)) 152 | 153 | def __get_cost(self, cost_name, Y_pred): 154 | if cost_name == "cross_entropy": 155 | # the function first calculate softmax then calculate the 156 | # cross_entropy(-tf.reduce_sum(self.Y_gt*tf.log(Y_pred))), 157 | # logits don't through the tf.nn,softmax function 158 | cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=self.Y_gt, logits=Y_pred)) 159 | return cost 160 | if cost_name == "focal_loss": 161 | weight_loss = np.array(self.alpha) 162 | epsilon = 1.e-5 163 | # Scale predictions so that the class probas of each sample sum to 1 164 | output = Y_pred / tf.reduce_sum(Y_pred, axis=- 1, keepdims=True) 165 | # Clip the prediction value to prevent NaN's and Inf's 166 | output = tf.clip_by_value(output, epsilon, 1. - epsilon) 167 | # Calculate Cross Entropy 168 | cross_entropy = -self.Y_gt * tf.log(output) 169 | # Calculate Focal Loss 170 | loss = tf.pow(1 - output, self.gamma) * cross_entropy 171 | loss = tf.reduce_mean(loss, axis=0) 172 | loss = tf.reduce_mean(weight_loss * loss) 173 | return loss 174 | 175 | def __get_accuracy(self, Y_pred): 176 | correct_predict = tf.equal(tf.argmax(Y_pred, 1), tf.argmax(self.Y_gt, 1)) 177 | accuracy = tf.reduce_mean(tf.cast(correct_predict, 'float')) 178 | return accuracy 179 | 180 | def train(self, train_images, train_lanbels, model_path, logs_path, learning_rate, dropout_conv=0.8, train_epochs=5, 181 | batch_size=1): 182 | label_counts = np.unique(train_lanbels).shape[0] 183 | if not os.path.exists(logs_path): 184 | os.makedirs(logs_path) 185 | if not os.path.exists(logs_path + "model\\"): 186 | os.makedirs(logs_path + "model\\") 187 | model_path = logs_path + "model\\" + model_path 188 | # update the moving average of batch norm before finish the training step 189 | update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS) 190 | with tf.control_dependencies(update_ops): 191 | # ensures that we execute the update_ops before performing the train_step 192 | train_op = tf.train.AdamOptimizer(self.lr).minimize(self.cost) 193 | 194 | init = tf.global_variables_initializer() 195 | saver = tf.train.Saver(tf.all_variables(), max_to_keep=10) 196 | 197 | tf.summary.scalar("loss", self.cost) 198 | tf.summary.scalar("accuracy", self.accuracy) 199 | merged_summary_op = tf.summary.merge_all() 200 | 201 | summary_writer = tf.summary.FileWriter(logs_path, graph=tf.get_default_graph()) 202 | self.sess.run(init) 203 | 204 | DISPLAY_STEP = 1 205 | index_in_epoch = 0 206 | 207 | train_epochs = train_images.shape[0] * train_epochs 208 | for i in range(train_epochs): 209 | # get new batch 210 | batch_xs_path, batch_ys_path, index_in_epoch = _next_batch(train_images, train_lanbels, batch_size, 211 | index_in_epoch) 212 | # label one_hot coding 213 | train_labels_onehot = dense_to_one_hot(batch_ys_path, label_counts) 214 | batch_ys = train_labels_onehot.astype(np.float) 215 | train_images_data = np.empty((len(batch_xs_path), self.image_height, self.image_width, self.channels)) 216 | for num in range(len(batch_xs_path)): 217 | train_image = cv2.imread(batch_xs_path[num], 0) 218 | train_image = cv2.resize(train_image, (self.image_height, self.image_width)) 219 | batchimage = np.reshape(train_image, (self.image_height, self.image_width, self.channels)) 220 | train_images_data[num, :, :, :] = batchimage 221 | train_images_data = train_images_data.astype(np.float) 222 | # Normalize from [0:255] => [0.0:1.0] 223 | batch_xs = np.multiply(train_images_data, 1.0 / 255.0) 224 | # Extracting images and labels from given data 225 | batch_xs = batch_xs.astype(np.float) 226 | batch_ys = batch_ys.astype(np.float) 227 | # check progress on every 1st,2nd,...,10th,20th,...,100th... step 228 | if i % DISPLAY_STEP == 0 or (i + 1) == train_epochs: 229 | train_loss, train_accuracy = self.sess.run([self.cost, self.accuracy], 230 | feed_dict={self.X: batch_xs, 231 | self.Y_gt: batch_ys, 232 | self.lr: learning_rate, 233 | self.drop: 1, 234 | self.phase: 1}) 235 | print('epochs %d training_loss ,training_accuracy=> %.5f,%.5f ' % (i, train_loss, train_accuracy)) 236 | save_path = saver.save(self.sess, model_path, global_step=i) 237 | print("Model saved in file:", save_path) 238 | if i % (DISPLAY_STEP * 10) == 0 and i: 239 | DISPLAY_STEP *= 10 240 | 241 | # train on batch 242 | _, summary = self.sess.run([train_op, merged_summary_op], feed_dict={self.X: batch_xs, 243 | self.Y_gt: batch_ys, 244 | self.lr: learning_rate, 245 | self.drop: dropout_conv, 246 | self.phase: 1}) 247 | summary_writer.add_summary(summary, i) 248 | summary_writer.close() 249 | 250 | save_path = saver.save(self.sess, model_path) 251 | print("Model saved in file:", save_path) 252 | self.sess.close() 253 | 254 | def prediction(self, test_images): 255 | test_images = np.reshape(test_images, (1, test_images.shape[0], test_images.shape[1], 1)) 256 | predictvalue = np.zeros(test_images.shape[0]) 257 | predict_probvalue = np.zeros(test_images.shape[0], np.float) 258 | y_dummy = np.empty((test_images.shape[0], self.n_class)) 259 | for i in range(test_images.shape[0]): 260 | predictvaluetmp, predict_probvaluetmp = self.sess.run([self.predict, self.Y_pred], 261 | feed_dict={self.X: [test_images[i]], 262 | self.Y_gt: y_dummy, 263 | self.drop: 1, 264 | self.phase: 1}) 265 | predictvalue[i], predict_probvalue[i] = predictvaluetmp, predict_probvaluetmp[0][1] 266 | return predictvalue, predict_probvalue 267 | -------------------------------------------------------------------------------- /TNSCUI2020/dataprocess/Augmentation/images_masks_transform.py: -------------------------------------------------------------------------------- 1 | '''Fairly basic set of tools for real-time data augmentation on image data. 2 | Can easily be extended to include new transformations, 3 | new preprocessing methods, etc... 4 | Modified by junqiang Chen 12/2017 5 | 6 | For image segmentation problem data augmentation. 7 | Transform train img data and mask img data simultaneously and in the same fashion. 8 | Omit flow from directory function. 9 | ''' 10 | 11 | from __future__ import absolute_import 12 | from __future__ import print_function 13 | 14 | import numpy as np 15 | from scipy import linalg 16 | import scipy.ndimage as ndi 17 | import os 18 | import threading 19 | 20 | from keras import backend as K 21 | 22 | 23 | def random_channel_shift(x, intensity, channel_index=0): 24 | x = np.rollaxis(x, channel_index, 0) 25 | min_x, max_x = np.min(x), np.max(x) 26 | channel_images = [np.clip(x_channel + np.random.uniform(-intensity, intensity), min_x, max_x) 27 | for x_channel in x] 28 | x = np.stack(channel_images, axis=0) 29 | x = np.rollaxis(x, 0, channel_index + 1) 30 | return x 31 | 32 | 33 | def transform_matrix_offset_center(matrix, x, y): 34 | o_x = float(x) / 2 + 0.5 35 | o_y = float(y) / 2 + 0.5 36 | offset_matrix = np.array([[1, 0, o_x], [0, 1, o_y], [0, 0, 1]]) 37 | reset_matrix = np.array([[1, 0, -o_x], [0, 1, -o_y], [0, 0, 1]]) 38 | transform_matrix = np.dot(np.dot(offset_matrix, matrix), reset_matrix) 39 | return transform_matrix 40 | 41 | 42 | def apply_transform(x, transform_matrix, channel_index=0, fill_mode='nearest', cval=0.): 43 | x = np.rollaxis(x, channel_index, 0) 44 | final_affine_matrix = transform_matrix[:2, :2] 45 | final_offset = transform_matrix[:2, 2] 46 | channel_images = [ndi.interpolation.affine_transform(x_channel, final_affine_matrix, 47 | final_offset, order=0, mode=fill_mode, cval=cval) for x_channel 48 | in x] 49 | x = np.stack(channel_images, axis=0) 50 | x = np.rollaxis(x, 0, channel_index + 1) 51 | return x 52 | 53 | 54 | def flip_axis(x, axis): 55 | x = np.asarray(x).swapaxes(axis, 0) 56 | x = x[::-1, ...] 57 | x = x.swapaxes(0, axis) 58 | return x 59 | 60 | 61 | def array_to_img(x, dim_ordering='default', scale=True): 62 | from PIL import Image 63 | if dim_ordering == 'default': 64 | dim_ordering = K.image_dim_ordering() 65 | if dim_ordering == 'th': 66 | x = x.transpose(1, 2, 0) 67 | if scale: 68 | x += max(-np.min(x), 0) 69 | x /= np.max(x) 70 | x *= 255 71 | if x.shape[2] == 3: 72 | # RGB 73 | return Image.fromarray(x.astype('uint8'), 'RGB') 74 | elif x.shape[2] == 1: 75 | # grayscale 76 | return Image.fromarray(x[:, :, 0].astype('uint8'), 'L') 77 | else: 78 | raise Exception('Unsupported channel number: ', x.shape[2]) 79 | 80 | 81 | def img_to_array(img, dim_ordering='default'): 82 | if dim_ordering == 'default': 83 | dim_ordering = K.image_dim_ordering() 84 | if dim_ordering not in ['th', 'tf']: 85 | raise Exception('Unknown dim_ordering: ', dim_ordering) 86 | # image has dim_ordering (height, width, channel) 87 | x = np.asarray(img, dtype='float32') 88 | if len(x.shape) == 3: 89 | if dim_ordering == 'th': 90 | x = x.transpose(2, 0, 1) 91 | elif len(x.shape) == 2: 92 | if dim_ordering == 'th': 93 | x = x.reshape((1, x.shape[0], x.shape[1])) 94 | else: 95 | x = x.reshape((x.shape[0], x.shape[1], 1)) 96 | else: 97 | raise Exception('Unsupported image shape: ', x.shape) 98 | return x 99 | 100 | 101 | class ImageDataGenerator(object): 102 | '''Generate minibatches with 103 | real-time data augmentation. 104 | Assume X is train img, Y is train label (same size as X with only 0 and 255 for values) 105 | # Arguments 106 | featurewise_center: set input mean to 0 over the dataset. Only to X 107 | samplewise_center: set each sample mean to 0. Only to X 108 | featurewise_std_normalization: divide inputs by std of the dataset. Only to X 109 | samplewise_std_normalization: divide each input by its std. Only to X 110 | zca_whitening: apply ZCA whitening. Only to X 111 | rotation_range: degrees (0 to 180). To X and Y 112 | width_shift_range: fraction of total width. To X and Y 113 | height_shift_range: fraction of total height. To X and Y 114 | shear_range: shear intensity (shear angle in radians). To X and Y 115 | zoom_range: amount of zoom. if scalar z, zoom will be randomly picked 116 | in the range [1-z, 1+z]. A sequence of two can be passed instead 117 | to select this range. To X and Y 118 | channel_shift_range: shift range for each channels. Only to X 119 | fill_mode: points outside the boundaries are filled according to the 120 | given mode ('constant', 'nearest', 'reflect' or 'wrap'). Default 121 | is 'nearest'. For Y, always fill with constant 0 122 | cval: value used for points outside the boundaries when fill_mode is 123 | 'constant'. Default is 0. 124 | horizontal_flip: whether to randomly flip images horizontally. To X and Y 125 | vertical_flip: whether to randomly flip images vertically. To X and Y 126 | rescale: rescaling factor. If None or 0, no rescaling is applied, 127 | otherwise we multiply the data by the value provided (before applying 128 | any other transformation). Only to X 129 | dim_ordering: 'th' or 'tf'. In 'th' mode, the channels dimension 130 | (the depth) is at index 1, in 'tf' mode it is at index 3. 131 | It defaults to the `image_dim_ordering` value found in your 132 | Keras config file at `~/.keras/keras.json`. 133 | If you never set it, then it will be "th". 134 | ''' 135 | 136 | def __init__(self, 137 | featurewise_center=False, 138 | samplewise_center=False, 139 | featurewise_std_normalization=False, 140 | samplewise_std_normalization=False, 141 | zca_whitening=False, 142 | rotation_range=0., 143 | width_shift_range=0., 144 | height_shift_range=0., 145 | shear_range=0., 146 | zoom_range=0., 147 | channel_shift_range=0., 148 | fill_mode='nearest', 149 | cval=0., 150 | horizontal_flip=False, 151 | vertical_flip=False, 152 | rescale=None, 153 | dim_ordering='default'): 154 | self.featurewise_center = featurewise_center 155 | self.samplewise_center = samplewise_center 156 | self.featurewise_std_normalization = featurewise_std_normalization 157 | self.samplewise_std_normalization = samplewise_std_normalization 158 | self.zca_whitening = zca_whitening 159 | self.rotation_range = rotation_range 160 | self.width_shift_range = width_shift_range 161 | self.height_shift_range = height_shift_range 162 | self.shear_range = shear_range 163 | self.channel_shift_range = channel_shift_range 164 | self.fill_mode = fill_mode 165 | self.cval = cval 166 | self.horizontal_flip = horizontal_flip 167 | self.vertical_flip = vertical_flip 168 | self.rescale = rescale 169 | 170 | if dim_ordering == 'default': 171 | dim_ordering = 'tf' 172 | else: 173 | dim_ordering = 'th' 174 | self.__dict__.update(locals()) 175 | self.mean = None 176 | self.std = None 177 | self.principal_components = None 178 | 179 | if dim_ordering not in {'tf', 'th'}: 180 | raise Exception('dim_ordering should be "tf" (channel after row and ' 181 | 'column) or "th" (channel before row and column). ' 182 | 'Received arg: ', dim_ordering) 183 | self.dim_ordering = dim_ordering 184 | if dim_ordering == 'th': 185 | self.channel_index = 1 186 | self.row_index = 2 187 | self.col_index = 3 188 | if dim_ordering == 'tf': 189 | self.channel_index = 3 190 | self.row_index = 1 191 | self.col_index = 2 192 | 193 | if np.isscalar(zoom_range): 194 | self.zoom_range = [1 - zoom_range, 1 + zoom_range] 195 | elif len(zoom_range) == 2: 196 | self.zoom_range = [zoom_range[0], zoom_range[1]] 197 | else: 198 | raise Exception('zoom_range should be a float or ' 199 | 'a tuple or list of two floats. ' 200 | 'Received arg: ', zoom_range) 201 | 202 | def flow(self, X, y=None, batch_size=32, shuffle=True, seed=None, 203 | save_to_dir=None, save_prefix='', save_format='jpeg'): 204 | return NumpyArrayIterator( 205 | X, y, self, 206 | batch_size=batch_size, shuffle=shuffle, seed=seed, 207 | dim_ordering=self.dim_ordering, 208 | save_to_dir=save_to_dir, save_prefix=save_prefix, save_format=save_format) 209 | 210 | def standardize(self, x): 211 | # Only applied to X 212 | if self.rescale: 213 | x *= self.rescale 214 | # x is a single image, so it doesn't have image number at index 0 215 | img_channel_index = self.channel_index - 1 216 | if self.samplewise_center: 217 | x -= np.mean(x, axis=img_channel_index, keepdims=True) 218 | if self.samplewise_std_normalization: 219 | x /= (np.std(x, axis=img_channel_index, keepdims=True) + 1e-7) 220 | 221 | if self.featurewise_center: 222 | x -= self.mean 223 | if self.featurewise_std_normalization: 224 | x /= (self.std + 1e-7) 225 | 226 | if self.zca_whitening: 227 | flatx = np.reshape(x, (x.size)) 228 | whitex = np.dot(flatx, self.principal_components) 229 | x = np.reshape(whitex, (x.shape[0], x.shape[1], x.shape[2])) 230 | 231 | return x 232 | 233 | def random_transform(self, x, y): 234 | # Need to modify to transform both X and Y ---- to do 235 | # x is a single image, so it doesn't have image number at index 0 236 | img_row_index = self.row_index - 1 237 | img_col_index = self.col_index - 1 238 | img_channel_index = self.channel_index - 1 239 | 240 | # use composition of homographies to generate final transform that needs to be applied 241 | if self.rotation_range: 242 | theta = np.pi / 180 * np.random.uniform(-self.rotation_range, self.rotation_range) 243 | else: 244 | theta = 0 245 | rotation_matrix = np.array([[np.cos(theta), -np.sin(theta), 0], 246 | [np.sin(theta), np.cos(theta), 0], 247 | [0, 0, 1]]) 248 | if self.height_shift_range: 249 | tx = np.random.uniform(-self.height_shift_range, self.height_shift_range) * x.shape[img_row_index] 250 | else: 251 | tx = 0 252 | 253 | if self.width_shift_range: 254 | ty = np.random.uniform(-self.width_shift_range, self.width_shift_range) * x.shape[img_col_index] 255 | else: 256 | ty = 0 257 | 258 | translation_matrix = np.array([[1, 0, tx], 259 | [0, 1, ty], 260 | [0, 0, 1]]) 261 | if self.shear_range: 262 | shear = np.random.uniform(-self.shear_range, self.shear_range) 263 | else: 264 | shear = 0 265 | shear_matrix = np.array([[1, -np.sin(shear), 0], 266 | [0, np.cos(shear), 0], 267 | [0, 0, 1]]) 268 | 269 | if self.zoom_range[0] == 1 and self.zoom_range[1] == 1: 270 | zx, zy = 1, 1 271 | else: 272 | zx, zy = np.random.uniform(self.zoom_range[0], self.zoom_range[1], 2) 273 | zoom_matrix = np.array([[zx, 0, 0], 274 | [0, zy, 0], 275 | [0, 0, 1]]) 276 | 277 | transform_matrix = np.dot(np.dot(np.dot(rotation_matrix, translation_matrix), shear_matrix), zoom_matrix) 278 | 279 | h, w = x.shape[img_row_index], x.shape[img_col_index] 280 | transform_matrix = transform_matrix_offset_center(transform_matrix, h, w) 281 | x = apply_transform(x, transform_matrix, img_channel_index, 282 | fill_mode=self.fill_mode, cval=self.cval) 283 | # For y, mask data, fill mode constant, cval = 0 284 | y = apply_transform(y, transform_matrix, img_channel_index, 285 | fill_mode=self.fill_mode, cval=self.cval) 286 | 287 | if self.channel_shift_range != 0: 288 | x = random_channel_shift(x, self.channel_shift_range, img_channel_index) 289 | 290 | if self.horizontal_flip: 291 | if np.random.random() < 0.5: 292 | x = flip_axis(x, img_col_index) 293 | y = flip_axis(y, img_col_index) 294 | 295 | if self.vertical_flip: 296 | if np.random.random() < 0.5: 297 | x = flip_axis(x, img_row_index) 298 | y = flip_axis(y, img_row_index) 299 | 300 | # TODO: 301 | # channel-wise normalization 302 | # barrel/fisheye 303 | return x, y 304 | 305 | def fit(self, X, 306 | augment=False, 307 | rounds=1, 308 | seed=None): 309 | '''Required for featurewise_center, featurewise_std_normalization 310 | and zca_whitening. 311 | # Arguments 312 | X: Numpy array, the data to fit on. 313 | augment: whether to fit on randomly augmented samples 314 | rounds: if `augment`, 315 | how many augmentation passes to do over the data 316 | seed: random seed. 317 | # Only applied to X 318 | ''' 319 | X = np.copy(X) 320 | if augment: 321 | aX = np.zeros(tuple([rounds * X.shape[0]] + list(X.shape)[1:])) 322 | for r in range(rounds): 323 | for i in range(X.shape[0]): 324 | aX[i + r * X.shape[0]] = self.random_transform(X[i]) 325 | X = aX 326 | 327 | if self.featurewise_center: 328 | self.mean = np.mean(X, axis=0) 329 | X -= self.mean 330 | 331 | if self.featurewise_std_normalization: 332 | self.std = np.std(X, axis=0) 333 | X /= (self.std + 1e-7) 334 | 335 | if self.zca_whitening: 336 | flatX = np.reshape(X, (X.shape[0], X.shape[1] * X.shape[2] * X.shape[3])) 337 | sigma = np.dot(flatX.T, flatX) / flatX.shape[1] 338 | U, S, V = linalg.svd(sigma) 339 | self.principal_components = np.dot(np.dot(U, np.diag(1. / np.sqrt(S + 10e-7))), U.T) 340 | 341 | 342 | class Iterator(object): 343 | def __init__(self, N, batch_size, shuffle, seed): 344 | self.N = N 345 | self.batch_size = batch_size 346 | self.shuffle = shuffle 347 | self.batch_index = 0 348 | self.total_batches_seen = 0 349 | self.lock = threading.Lock() 350 | self.index_generator = self._flow_index(N, batch_size, shuffle, seed) 351 | 352 | def reset(self): 353 | self.batch_index = 0 354 | 355 | def _flow_index(self, N, batch_size=32, shuffle=False, seed=None): 356 | # ensure self.batch_index is 0 357 | self.reset() 358 | while 1: 359 | if self.batch_index == 0: 360 | index_array = np.arange(N) 361 | if shuffle: 362 | if seed is not None: 363 | np.random.seed(seed + self.total_batches_seen) 364 | index_array = np.random.permutation(N) 365 | 366 | current_index = (self.batch_index * batch_size) % N 367 | if N >= current_index + batch_size: 368 | current_batch_size = batch_size 369 | self.batch_index += 1 370 | else: 371 | current_batch_size = N - current_index 372 | self.batch_index = 0 373 | self.total_batches_seen += 1 374 | yield (index_array[current_index: current_index + current_batch_size], 375 | current_index, current_batch_size) 376 | 377 | def __iter__(self): 378 | # needed if we want to do something like: 379 | # for x, y in data_gen.flow(...): 380 | return self 381 | 382 | def __next__(self, *args, **kwargs): 383 | # ? 384 | return self.next(*args, **kwargs) 385 | 386 | 387 | class NumpyArrayIterator(Iterator): 388 | def __init__(self, X, y, image_data_generator, 389 | batch_size=32, shuffle=False, seed=None, 390 | dim_ordering='default', 391 | save_to_dir=None, save_prefix='', save_format='jpeg'): 392 | if len(X) != len(y): 393 | raise Exception('X (images tensor) and y (labels) ' 394 | 'should have the same length. ' 395 | 'Found: X.shape = %s, y.shape = %s' % (np.asarray(X).shape, np.asarray(y).shape)) 396 | if dim_ordering == 'default': 397 | dim_ordering = K.image_dim_ordering() 398 | self.X = X 399 | self.y = y 400 | self.image_data_generator = image_data_generator 401 | self.dim_ordering = dim_ordering 402 | self.save_to_dir = save_to_dir 403 | self.save_prefix = save_prefix 404 | self.save_format = save_format 405 | super(NumpyArrayIterator, self).__init__(X.shape[0], batch_size, shuffle, seed) 406 | 407 | def next(self): 408 | # for python 2.x. 409 | # Keeps under lock only the mechanism which advances 410 | # the indexing of each batch 411 | # see http://anandology.com/blog/using-iterators-and-generators/ 412 | with self.lock: 413 | index_array, current_index, current_batch_size = next(self.index_generator) 414 | # The transformation of images is not under thread lock so it can be done in parallel 415 | batch_x = np.zeros(tuple([current_batch_size] + list(self.X.shape)[1:])) 416 | batch_y = np.zeros(tuple([current_batch_size] + list(self.y.shape)[1:])) 417 | for i, j in enumerate(index_array): 418 | x = self.X[j] 419 | label = self.y[j] 420 | x, label = self.image_data_generator.random_transform(x.astype('float32'), label.astype("float32")) 421 | x = self.image_data_generator.standardize(x) 422 | batch_x[i] = x 423 | batch_y[i] = label 424 | if self.save_to_dir: 425 | for i in range(current_batch_size): 426 | img = array_to_img(batch_x[i], self.dim_ordering, scale=True) 427 | fname = '{prefix}_{index}_{hash}.{format}'.format(prefix=self.save_prefix, 428 | index=current_index + i, 429 | hash=np.random.randint(1e4), 430 | format=self.save_format) 431 | img.save(os.path.join(self.save_to_dir, fname)) 432 | mask = array_to_img(batch_y[i], self.dim_ordering, scale=True) 433 | fname = '{prefix}_{index}_{hash}_mask.{format}'.format(prefix=self.save_prefix, 434 | index=current_index + i, 435 | hash=np.random.randint(1e4), 436 | format=self.save_format) 437 | mask.save(os.path.join(self.save_to_dir, fname)) 438 | return batch_x, batch_y 439 | -------------------------------------------------------------------------------- /Vnet2d/vnet_seg_classify_model.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | import cv2 4 | import numpy as np 5 | import tensorflow as tf 6 | 7 | from Vnet2d.layer import (conv2d, deconv2d, upsample2d, normalizationlayer, crop_and_concat, resnet_Add, 8 | weight_xavier_init, bias_variable, dense_to_one_hot) 9 | 10 | 11 | def conv_bn_relu_drop(x, kernalshape, phase, drop_conv, height=None, width=None, scope=None): 12 | with tf.name_scope(scope): 13 | W = weight_xavier_init(shape=kernalshape, n_inputs=kernalshape[0] * kernalshape[1] * kernalshape[2], 14 | n_outputs=kernalshape[-1], activefunction='relu', variable_name=str(scope) + 'W') 15 | B = bias_variable([kernalshape[-1]], variable_name=str(scope) + 'B') 16 | conv = conv2d(x, W) + B 17 | conv = normalizationlayer(conv, phase, height=height, width=width, norm_type='group', scope=scope) 18 | conv = tf.nn.dropout(tf.nn.relu(conv), drop_conv) 19 | return conv 20 | 21 | 22 | def down_sampling(x, kernalshape, phase, drop_conv, height=None, width=None, scope=None): 23 | with tf.name_scope(scope): 24 | W = weight_xavier_init(shape=kernalshape, n_inputs=kernalshape[0] * kernalshape[1] * kernalshape[2], 25 | n_outputs=kernalshape[-1], activefunction='relu', variable_name=str(scope) + 'W') 26 | B = bias_variable([kernalshape[-1]], variable_name=str(scope) + 'B') 27 | conv = conv2d(x, W, 2) + B 28 | conv = normalizationlayer(conv, phase, height=height, width=width, norm_type='group', scope=scope) 29 | conv = tf.nn.dropout(tf.nn.relu(conv), drop_conv) 30 | return conv 31 | 32 | 33 | def deconv_relu_drop(x, kernalshape, samefeture=False, scope=None): 34 | with tf.name_scope(scope): 35 | W = weight_xavier_init(shape=kernalshape, n_inputs=kernalshape[0] * kernalshape[1] * kernalshape[-1], 36 | n_outputs=kernalshape[-2], activefunction='relu', variable_name=str(scope) + 'W') 37 | B = bias_variable([kernalshape[-2]], variable_name=str(scope) + 'B') 38 | dconv = tf.nn.relu(deconv2d(x, W, samefeature=samefeture) + B) 39 | return dconv 40 | 41 | 42 | def conv_sigmod(x, kernalshape, scope=None): 43 | with tf.name_scope(scope): 44 | W = weight_xavier_init(shape=kernalshape, n_inputs=kernalshape[0] * kernalshape[1] * kernalshape[2], 45 | n_outputs=kernalshape[-1], activefunction='sigomd', variable_name=str(scope) + 'W') 46 | B = bias_variable([kernalshape[-1]], variable_name=str(scope) + 'B') 47 | conv = conv2d(x, W) + B 48 | conv = tf.nn.sigmoid(conv) 49 | return conv 50 | 51 | 52 | def conv_softmax(x, kernalshape, scope=None): 53 | with tf.name_scope(scope): 54 | W = weight_xavier_init(shape=kernalshape, n_inputs=kernalshape[0] * kernalshape[1] * kernalshape[2], 55 | n_outputs=kernalshape[-1], activefunction='sigomd', variable_name=str(scope) + 'W') 56 | B = bias_variable([kernalshape[-1]], variable_name=str(scope) + 'B') 57 | conv = conv2d(x, W) + B 58 | conv = tf.nn.softmax(conv) 59 | return conv 60 | 61 | 62 | def conv_relu(x, kernalshape, scope=None): 63 | with tf.name_scope(scope): 64 | W = weight_xavier_init(shape=kernalshape, n_inputs=kernalshape[0] * kernalshape[1] * kernalshape[2], 65 | n_outputs=kernalshape[-1], activefunction='relu', variable_name=str(scope) + 'W') 66 | B = bias_variable([kernalshape[-1]], variable_name=str(scope) + 'B') 67 | conv = conv2d(x, W) + B 68 | conv = tf.nn.relu(conv) 69 | return conv 70 | 71 | 72 | def full_connected_relu_drop(x, kernal, drop, activefunction='relu', scope=None): 73 | with tf.name_scope(scope): 74 | W = weight_xavier_init(shape=kernal, n_inputs=kernal[0] * kernal[1], 75 | n_outputs=kernal[-1], activefunction='relu', variable_name=scope + 'W') 76 | B = bias_variable([kernal[-1]], variable_name=scope + 'B') 77 | FC = tf.matmul(x, W) + B 78 | if activefunction == 'relu': 79 | FC = tf.nn.relu(FC) 80 | FC = tf.nn.dropout(FC, drop) 81 | elif activefunction == 'softmax': 82 | FC = tf.nn.softmax(FC) 83 | return FC 84 | 85 | 86 | def AGModel(x, signal, kernalshape, phase, height=None, width=None, scope=None): 87 | with tf.name_scope(scope): 88 | # attention input 89 | Wg = weight_xavier_init(shape=kernalshape, n_inputs=kernalshape[0] * kernalshape[1] * kernalshape[2], 90 | n_outputs=kernalshape[-1], activefunction='relu', variable_name=str(scope) + 'Wg') 91 | Bg = bias_variable([kernalshape[-1]], variable_name=str(scope) + 'Bg') 92 | convg = conv2d(signal, Wg) + Bg 93 | convg = normalizationlayer(convg, phase, height=height, width=width, norm_type='group', 94 | scope=str(scope) + 'normg') 95 | # input 96 | Wf = weight_xavier_init(shape=kernalshape, n_inputs=kernalshape[0] * kernalshape[1] * kernalshape[2], 97 | n_outputs=kernalshape[-1], activefunction='relu', variable_name=str(scope) + 'Wf') 98 | Bf = bias_variable([kernalshape[-1]], variable_name=str(scope) + 'Bf') 99 | convf = conv2d(x, Wf) + Bf 100 | convf = normalizationlayer(convf, phase, height=height, width=width, norm_type='group', 101 | scope=str(scope) + 'normf') 102 | # add input and attention input 103 | convadd = resnet_Add(x1=convg, x2=convf) 104 | convadd = tf.nn.relu(convadd) 105 | 106 | # generate attention gat coe 107 | attencoekernalshape = (1, 1, kernalshape[-1], 1) 108 | Wpsi = weight_xavier_init(shape=attencoekernalshape, 109 | n_inputs=attencoekernalshape[0] * attencoekernalshape[1] * attencoekernalshape[2], 110 | n_outputs=attencoekernalshape[-1], activefunction='sigomd', 111 | variable_name=str(scope) + 'Wpsi') 112 | Bpsi = bias_variable([attencoekernalshape[-1]], variable_name=str(scope) + 'Bpsi') 113 | convpsi = conv2d(convadd, Wpsi) + Bpsi 114 | convpsi = normalizationlayer(convpsi, phase, height=height, width=width, norm_type='group', 115 | scope=str(scope) + 'normpsi') 116 | convpsi = tf.nn.sigmoid(convpsi) 117 | # generate attention gat coe 118 | attengatx = tf.multiply(x, convpsi) 119 | return attengatx 120 | 121 | 122 | def _create_conv_net(X, image_width, image_height, image_channel, phase, drop_conv, n_class=1, n_classify=2): 123 | inputX = tf.reshape(X, [-1, image_width, image_height, image_channel]) # shape=(?, 32, 32, 1) 124 | # VNet model 125 | # layer0->convolution 126 | layer0 = conv_relu(x=inputX, kernalshape=(3, 3, image_channel, 16), scope='layer0') 127 | # layer1->convolution 128 | layer1 = conv_bn_relu_drop(x=layer0, kernalshape=(3, 3, 16, 16), phase=phase, drop_conv=drop_conv, 129 | scope='layer1-1') 130 | layer1 = conv_bn_relu_drop(x=layer1, kernalshape=(3, 3, 16, 16), phase=phase, drop_conv=drop_conv, 131 | scope='layer1-2') 132 | layer1 = resnet_Add(x1=layer0, x2=layer1) 133 | # down sampling1 134 | down1 = down_sampling(x=layer1, kernalshape=(3, 3, 16, 32), phase=phase, drop_conv=drop_conv, scope='down1') 135 | # layer2->convolution 136 | layer2 = conv_bn_relu_drop(x=down1, kernalshape=(3, 3, 32, 32), phase=phase, drop_conv=drop_conv, 137 | scope='layer2_1') 138 | layer2 = conv_bn_relu_drop(x=layer2, kernalshape=(3, 3, 32, 32), phase=phase, drop_conv=drop_conv, 139 | scope='layer2_2') 140 | layer2 = resnet_Add(x1=down1, x2=layer2) 141 | # down sampling2 142 | down2 = down_sampling(x=layer2, kernalshape=(3, 3, 32, 64), phase=phase, drop_conv=drop_conv, scope='down2') 143 | # layer3->convolution 144 | layer3 = conv_bn_relu_drop(x=down2, kernalshape=(3, 3, 64, 64), phase=phase, drop_conv=drop_conv, 145 | scope='layer3_1') 146 | layer3 = conv_bn_relu_drop(x=layer3, kernalshape=(3, 3, 64, 64), phase=phase, drop_conv=drop_conv, 147 | scope='layer3_2') 148 | layer3 = conv_bn_relu_drop(x=layer3, kernalshape=(3, 3, 64, 64), phase=phase, drop_conv=drop_conv, 149 | scope='layer3_3') 150 | layer3 = resnet_Add(x1=down2, x2=layer3) 151 | # down sampling3 152 | down3 = down_sampling(x=layer3, kernalshape=(3, 3, 64, 128), phase=phase, drop_conv=drop_conv, scope='down3') 153 | # layer4->convolution 154 | layer4 = conv_bn_relu_drop(x=down3, kernalshape=(3, 3, 128, 128), phase=phase, drop_conv=drop_conv, 155 | scope='layer4_1') 156 | layer4 = conv_bn_relu_drop(x=layer4, kernalshape=(3, 3, 128, 128), phase=phase, drop_conv=drop_conv, 157 | scope='layer4_2') 158 | layer4 = conv_bn_relu_drop(x=layer4, kernalshape=(3, 3, 128, 128), phase=phase, drop_conv=drop_conv, 159 | scope='layer4_3') 160 | layer4 = resnet_Add(x1=down3, x2=layer4) 161 | # down sampling4 162 | down4 = down_sampling(x=layer4, kernalshape=(3, 3, 128, 256), phase=phase, drop_conv=drop_conv, scope='down4') 163 | # layer5->convolution 164 | layer5 = conv_bn_relu_drop(x=down4, kernalshape=(3, 3, 256, 256), phase=phase, drop_conv=drop_conv, 165 | scope='layer5_1') 166 | layer5 = conv_bn_relu_drop(x=layer5, kernalshape=(3, 3, 256, 256), phase=phase, drop_conv=drop_conv, 167 | scope='layer5_2') 168 | layer5 = conv_bn_relu_drop(x=layer5, kernalshape=(3, 3, 256, 256), phase=phase, drop_conv=drop_conv, 169 | scope='layer5_3') 170 | layer5 = resnet_Add(x1=down4, x2=layer5) 171 | # down sampling5 172 | down5 = down_sampling(x=layer5, kernalshape=(3, 3, 256, 512), phase=phase, drop_conv=drop_conv, scope='down5') 173 | # layer6->convolution 174 | layer6 = conv_bn_relu_drop(x=down5, kernalshape=(3, 3, 512, 512), phase=phase, drop_conv=drop_conv, 175 | scope='layer6_1') 176 | layer6 = conv_bn_relu_drop(x=layer6, kernalshape=(3, 3, 512, 512), phase=phase, drop_conv=drop_conv, 177 | scope='layer6_2') 178 | layer6 = conv_bn_relu_drop(x=layer6, kernalshape=(3, 3, 512, 512), phase=phase, drop_conv=drop_conv, 179 | scope='layer6_3') 180 | layer6 = resnet_Add(x1=down5, x2=layer6) 181 | 182 | gap = tf.reduce_mean(layer6, axis=(1, 2)) 183 | # layer7->FC1 184 | layerfc1 = tf.reshape(gap, [-1, 512]) # shape=(?, 512) 185 | layerfc2 = full_connected_relu_drop(x=layerfc1, kernal=(512, 512), drop=drop_conv, activefunction='relu', 186 | scope='fc1') 187 | # layer7->output 188 | classify_output = full_connected_relu_drop(x=layerfc2, kernal=(512, n_classify), drop=drop_conv, 189 | activefunction='regression', scope='classify_output') 190 | # layer7->deconvolution 191 | deconv1 = deconv_relu_drop(x=layer6, kernalshape=(3, 3, 256, 512), scope='deconv1') 192 | # layer8->convolution 193 | layer7 = crop_and_concat(layer5, deconv1) 194 | _, H, W, _ = layer5.get_shape().as_list() 195 | layer7 = conv_bn_relu_drop(x=layer7, kernalshape=(3, 3, 512, 256), height=H, width=W, phase=phase, 196 | drop_conv=drop_conv, scope='layer7_1') 197 | layer7 = conv_bn_relu_drop(x=layer7, kernalshape=(3, 3, 256, 256), height=H, width=W, phase=phase, 198 | drop_conv=drop_conv, scope='layer7_2') 199 | layer7 = conv_bn_relu_drop(x=layer7, kernalshape=(3, 3, 256, 256), height=H, width=W, phase=phase, 200 | drop_conv=drop_conv, scope='layer7_3') 201 | layer7 = resnet_Add(x1=deconv1, x2=layer7) 202 | # layer9->deconvolution 203 | deconv2 = deconv_relu_drop(x=layer7, kernalshape=(3, 3, 128, 256), scope='deconv2') 204 | # layer8->convolution 205 | layer8 = crop_and_concat(layer4, deconv2) 206 | _, H, W, _ = layer4.get_shape().as_list() 207 | layer8 = conv_bn_relu_drop(x=layer8, kernalshape=(3, 3, 256, 128), height=H, width=W, phase=phase, 208 | drop_conv=drop_conv, scope='layer8_1') 209 | layer8 = conv_bn_relu_drop(x=layer8, kernalshape=(3, 3, 128, 128), height=H, width=W, phase=phase, 210 | drop_conv=drop_conv, scope='layer8_2') 211 | layer8 = conv_bn_relu_drop(x=layer8, kernalshape=(3, 3, 128, 128), height=H, width=W, phase=phase, 212 | drop_conv=drop_conv, scope='layer8_3') 213 | layer8 = resnet_Add(x1=deconv2, x2=layer8) 214 | # layer9->deconvolution 215 | deconv3 = deconv_relu_drop(x=layer8, kernalshape=(3, 3, 64, 128), scope='deconv3') 216 | # layer8->convolution 217 | layer9 = crop_and_concat(layer3, deconv3) 218 | _, H, W, _ = layer3.get_shape().as_list() 219 | layer9 = conv_bn_relu_drop(x=layer9, kernalshape=(3, 3, 128, 64), height=H, width=W, phase=phase, 220 | drop_conv=drop_conv, scope='layer9_1') 221 | layer9 = conv_bn_relu_drop(x=layer9, kernalshape=(3, 3, 64, 64), height=H, width=W, phase=phase, 222 | drop_conv=drop_conv, scope='layer9_2') 223 | layer9 = conv_bn_relu_drop(x=layer9, kernalshape=(3, 3, 64, 64), height=H, width=W, phase=phase, 224 | drop_conv=drop_conv, scope='layer9_3') 225 | layer9 = resnet_Add(x1=deconv3, x2=layer9) 226 | # layer9->deconvolution 227 | deconv4 = deconv_relu_drop(x=layer9, kernalshape=(3, 3, 32, 64), scope='deconv4') 228 | # layer8->convolution 229 | layer10 = crop_and_concat(layer2, deconv4) 230 | _, H, W, _ = layer2.get_shape().as_list() 231 | layer10 = conv_bn_relu_drop(x=layer10, kernalshape=(3, 3, 64, 32), height=H, width=W, phase=phase, 232 | drop_conv=drop_conv, scope='layer10_1') 233 | layer10 = conv_bn_relu_drop(x=layer10, kernalshape=(3, 3, 32, 32), height=H, width=W, phase=phase, 234 | drop_conv=drop_conv, scope='layer10_2') 235 | layer10 = resnet_Add(x1=deconv4, x2=layer10) 236 | # layer9->deconvolution 237 | deconv5 = deconv_relu_drop(x=layer10, kernalshape=(3, 3, 16, 32), scope='deconv5') 238 | # layer8->convolution 239 | layer11 = crop_and_concat(layer1, deconv5) 240 | _, H, W, _ = layer1.get_shape().as_list() 241 | layer11 = conv_bn_relu_drop(x=layer11, kernalshape=(3, 3, 32, 16), height=H, width=W, phase=phase, 242 | drop_conv=drop_conv, scope='layer11_1') 243 | layer11 = conv_bn_relu_drop(x=layer11, kernalshape=(3, 3, 16, 16), height=H, width=W, phase=phase, 244 | drop_conv=drop_conv, scope='layer11_2') 245 | layer11 = resnet_Add(x1=deconv5, x2=layer11) 246 | # layer14->output 247 | output_map = conv_sigmod(x=layer11, kernalshape=(1, 1, 16, n_class), scope='output') 248 | return output_map, classify_output 249 | 250 | 251 | def _next_batch(train_images, train_masks, train_labels, batch_size, index_in_epoch): 252 | start = index_in_epoch 253 | index_in_epoch += batch_size 254 | num_examples = train_images.shape[0] 255 | # when all trainig data have been already used, it is reorder randomly 256 | if index_in_epoch > num_examples: 257 | # shuffle the data 258 | perm = np.arange(num_examples) 259 | np.random.shuffle(perm) 260 | train_images = train_images[perm] 261 | train_masks = train_masks[perm] 262 | train_labels = train_labels[perm] 263 | # start next epoch 264 | start = 0 265 | index_in_epoch = batch_size 266 | assert batch_size <= num_examples 267 | end = index_in_epoch 268 | return train_images[start:end], train_masks[start:end], train_labels[start:end], index_in_epoch 269 | 270 | 271 | class Vnet2dmutiltaskModule(object): 272 | """ 273 | A Vnet2d implementation 274 | 275 | :param image_height: number of height in the input image 276 | :param image_width: number of width in the input image 277 | :param channels: number of channels in the input image 278 | :param n_class: number of output labels 279 | :param costname: name of the cost function.Default is "cross_entropy" 280 | """ 281 | 282 | def __init__(self, image_height, image_width, channels=1, n_class=2, inference=False, model_path=None, 283 | costname=("dice coefficient", "cross_entropy")): 284 | self.image_width = image_width 285 | self.image_height = image_height 286 | self.channels = channels 287 | self.n_class = n_class 288 | self.alpha = 0.25 289 | self.gamma = 4 290 | self.weight = 2 291 | 292 | self.X = tf.placeholder("float", shape=[None, image_height, image_width, channels], name="Input") 293 | self.Y_gt = tf.placeholder("float", shape=[None, image_height, image_width, channels], name="Output_GT") 294 | self.Label_gt = tf.placeholder("float", shape=[None, self.n_class], name="Output_LabelGT") 295 | self.lr = tf.placeholder('float', name="Learning_rate") 296 | self.phase = tf.placeholder(tf.bool, name="Phase") 297 | self.drop_conv = tf.placeholder('float', name="DropOut") 298 | 299 | self.Y_pred, self.Label_pred_logits = _create_conv_net(self.X, self.image_width, 300 | self.image_height, 301 | self.channels, 302 | self.phase, 303 | self.drop_conv) 304 | self.Label_pred = tf.nn.softmax(self.Label_pred_logits) 305 | self.Label = tf.argmax(self.Label_pred, 1) 306 | 307 | self.segcost = self.__get_cost(costname[0], self.Y_gt, self.Y_pred) 308 | self.classifycost = self.__get_cost(costname[1], self.Label_gt, self.Label_pred_logits) 309 | 310 | self.cost = tf.reduce_mean(self.weight * self.segcost + self.classifycost) 311 | 312 | self.segaccuracy = self.__get_accuracy("dice coefficient", self.Y_gt, self.Y_pred) 313 | self.classifyaccuracy = self.__get_accuracy("classify accuracy", self.Label_gt, self.Label_pred) 314 | 315 | if inference: 316 | init = tf.global_variables_initializer() 317 | saver = tf.train.Saver() 318 | self.sess = tf.InteractiveSession() 319 | self.sess.run(init) 320 | saver.restore(self.sess, model_path) 321 | 322 | def __get_cost(self, cost_name, Y_gt, Y_pred): 323 | if cost_name == "cross_entropy": 324 | # the function first calculate softmax then calculate the 325 | # cross_entropy(-tf.reduce_sum(self.Y_gt*tf.log(Y_pred))), 326 | # logits don't through the tf.nn,softmax function 327 | loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=Y_gt, logits=Y_pred)) 328 | return loss 329 | if cost_name == "dice coefficient": 330 | H, W, C = Y_gt.get_shape().as_list()[1:] 331 | smooth = 1e-5 332 | pred_flat = tf.reshape(Y_pred, [-1, H * W * C]) 333 | true_flat = tf.reshape(Y_gt, [-1, H * W * C]) 334 | intersection = 2 * tf.reduce_sum(pred_flat * true_flat, axis=1) + smooth 335 | denominator = tf.reduce_sum(pred_flat, axis=1) + tf.reduce_sum(true_flat, axis=1) + smooth 336 | loss = 1 - tf.reduce_mean(intersection / denominator) 337 | return loss 338 | if cost_name == "pixelwise_cross entroy": 339 | H, W, C = Y_gt.get_shape().as_list()[1:] 340 | assert (C == 1) 341 | flat_logit = tf.reshape(Y_pred, [-1]) 342 | flat_label = tf.reshape(Y_gt, [-1]) 343 | loss = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits=flat_logit, labels=flat_label)) 344 | return loss 345 | if cost_name == "focal loss": 346 | epsilon = 1.e-5 347 | pt_1 = tf.where(tf.equal(Y_gt, 1), Y_pred, tf.ones_like(Y_pred)) 348 | pt_0 = tf.where(tf.equal(Y_gt, 0), Y_pred, tf.zeros_like(Y_pred)) 349 | # clip to prevent NaN's and Inf's 350 | pt_1 = tf.clip_by_value(pt_1, epsilon, 1. - epsilon) 351 | pt_0 = tf.clip_by_value(pt_0, epsilon, 1. - epsilon) 352 | loss_1 = self.alpha * tf.pow(1. - pt_1, self.gamma) * tf.log(pt_1) 353 | loss_0 = (1 - self.alpha) * tf.pow(pt_0, self.gamma) * tf.log(1. - pt_0) 354 | loss = -tf.reduce_sum(loss_1 + loss_0) 355 | loss = tf.reduce_mean(loss) 356 | return loss 357 | 358 | def __get_accuracy(self, accuracy_name, Y_gt, Y_pred, prob=0.8): 359 | """ 360 | binary iou 361 | :param Y_pred:A tensor resulting from a sigmod 362 | :param Y_gt:A tensor of the same shape as `output` 363 | :return: binary iou 364 | """ 365 | if accuracy_name == "dice coefficient": 366 | Y_pred_part = tf.to_float(Y_pred > prob) 367 | Y_pred_part = tf.cast(Y_pred_part, tf.float32) 368 | Y_gt_part = tf.identity(Y_gt) 369 | Y_gt_part = tf.cast(Y_gt_part, tf.float32) 370 | H, W, C = Y_gt.get_shape().as_list()[1:] 371 | smooth = 1.e-5 372 | smooth_tf = tf.constant(smooth, tf.float32) 373 | pred_flat = tf.reshape(Y_pred_part, [-1, H * W * C]) 374 | true_flat = tf.reshape(Y_gt_part, [-1, H * W * C]) 375 | intersection = tf.reduce_sum(pred_flat * true_flat, axis=-1) 376 | union = tf.reduce_sum(pred_flat, axis=-1) + tf.reduce_sum(true_flat, axis=-1) - intersection 377 | metric = tf.reduce_mean((intersection + smooth_tf) / (union + smooth_tf)) 378 | metric = tf.cond(tf.is_inf(metric), lambda: smooth_tf, lambda: metric) 379 | return metric 380 | if accuracy_name == "classify accuracy": 381 | correct_predict = tf.equal(tf.argmax(Y_pred, 1), tf.argmax(Y_gt, 1)) 382 | accuracy = tf.reduce_mean(tf.cast(correct_predict, 'float')) 383 | return accuracy 384 | 385 | def train(self, train_images, train_mask, train_labels, model_name, logs_path, learning_rate, 386 | dropout_conv=0.5, train_epochs=10, batch_size=1): 387 | label_counts = np.unique(train_labels).shape[0] 388 | if not os.path.exists(logs_path): 389 | os.makedirs(logs_path) 390 | if not os.path.exists(logs_path + "model\\"): 391 | os.makedirs(logs_path + "model\\") 392 | model_path = logs_path + "model\\" + model_name 393 | train_op = tf.train.AdamOptimizer(self.lr).minimize(self.cost) 394 | 395 | init = tf.global_variables_initializer() 396 | saver = tf.train.Saver(tf.all_variables(), max_to_keep=10) 397 | 398 | tf.summary.scalar("loss", self.cost) 399 | tf.summary.scalar("segaccuracy", self.segaccuracy) 400 | tf.summary.scalar("classifyaccuracy", self.classifyaccuracy) 401 | merged_summary_op = tf.summary.merge_all() 402 | sess = tf.InteractiveSession(config=tf.ConfigProto(allow_soft_placement=True, log_device_placement=False)) 403 | summary_writer = tf.summary.FileWriter(logs_path, graph=tf.get_default_graph()) 404 | sess.run(init) 405 | 406 | DISPLAY_STEP = 1 407 | index_in_epoch = 0 408 | 409 | train_epochs = train_images.shape[0] * train_epochs 410 | for i in range(train_epochs): 411 | # get new batch 412 | batch_xs_path, batch_ys_path, batch_label_path, index_in_epoch = _next_batch(train_images, train_mask, 413 | train_labels, batch_size, 414 | index_in_epoch) 415 | # label one_hot coding 416 | train_labels_onehot = dense_to_one_hot(batch_label_path, label_counts) 417 | batch_labels = train_labels_onehot.astype(np.float) 418 | 419 | batch_xs = np.empty((len(batch_xs_path), self.image_height, self.image_width, self.channels)) 420 | batch_ys = np.empty((len(batch_ys_path), self.image_height, self.image_width, self.channels)) 421 | 422 | for num in range(len(batch_xs_path)): 423 | image = cv2.imread(batch_xs_path[num], 0) 424 | label = cv2.imread(batch_ys_path[num], 0) 425 | image = cv2.resize(image, (self.image_width, self.image_height)) 426 | label = cv2.resize(label, (self.image_width, self.image_height)) 427 | batch_xs[num, :, :, :] = np.reshape(image, (self.image_height, self.image_width, self.channels)) 428 | batch_ys[num, :, :, :] = np.reshape(label, (self.image_height, self.image_width, self.channels)) 429 | # Extracting images and labels from given data 430 | batch_xs = batch_xs.astype(np.float) 431 | batch_ys = batch_ys.astype(np.float) 432 | batch_labels = batch_labels.astype(np.float) 433 | # Normalize from [0:255] => [0.0:1.0] 434 | batch_xs = np.multiply(batch_xs, 1.0 / 255.0) 435 | batch_ys = np.multiply(batch_ys, 1.0 / 255.0) 436 | # check progress on every 1st,2nd,...,10th,20th,...,100th... step 437 | if i % DISPLAY_STEP == 0 or (i + 1) == train_epochs: 438 | train_loss, train_segaccuracy, train_classifyaccuracy = sess.run([self.cost, self.segaccuracy, 439 | self.classifyaccuracy], 440 | feed_dict={self.X: batch_xs, 441 | self.Y_gt: batch_ys, 442 | self.Label_gt: batch_labels, 443 | self.lr: learning_rate, 444 | self.phase: 1, 445 | self.drop_conv: dropout_conv}) 446 | pred = sess.run(self.Y_pred, feed_dict={self.X: batch_xs, 447 | self.Y_gt: batch_ys, 448 | self.Label_gt: batch_labels, 449 | self.phase: 1, 450 | self.drop_conv: 1}) 451 | result = np.reshape(pred[0], (self.image_height, self.image_width)) 452 | result = result.astype(np.float32) * 255. 453 | result = np.clip(result, 0, 255).astype('uint8') 454 | result_path = logs_path + 'result_%d_epoch.png' % (i) 455 | cv2.imwrite(result_path, result) 456 | true = np.reshape(batch_ys[0], (self.image_height, self.image_width)) 457 | true = true.astype(np.float32) * 255. 458 | true = np.clip(true, 0, 255).astype('uint8') 459 | true_path = logs_path + 'src_%d_epoch.png' % (i) 460 | cv2.imwrite(true_path, true) 461 | print('epochs %d training_loss ,Training_segaccuracy,Training_classifyaccuracy => %.5f,%.5f,%.5f' % ( 462 | i, train_loss, train_segaccuracy, train_classifyaccuracy)) 463 | save_path = saver.save(sess, model_path, global_step=i) 464 | print("Model saved in file:", save_path) 465 | if i % (DISPLAY_STEP * 10) == 0 and i: 466 | DISPLAY_STEP *= 10 467 | # train on batch 468 | _, summary = sess.run([train_op, merged_summary_op], feed_dict={self.X: batch_xs, 469 | self.Y_gt: batch_ys, 470 | self.Label_gt: batch_labels, 471 | self.lr: learning_rate, 472 | self.phase: 1, 473 | self.drop_conv: dropout_conv}) 474 | summary_writer.add_summary(summary, i) 475 | summary_writer.close() 476 | save_path = saver.save(sess, model_path) 477 | print("Model saved in file:", save_path) 478 | 479 | def prediction(self, test_images, prob=0.8): 480 | test_images = test_images.astype(np.float) 481 | test_images = np.reshape(test_images, (1, test_images.shape[0], test_images.shape[1], 1)) 482 | y_dummy = np.empty((1, self.n_class)) 483 | segpred, label_prob, label = self.sess.run([self.Y_pred, self.Label_pred, self.Label], 484 | feed_dict={self.X: test_images, 485 | self.Y_gt: test_images, 486 | self.Label_gt: y_dummy, 487 | self.phase: 1, 488 | self.drop_conv: 1}) 489 | result = np.reshape(segpred, (test_images.shape[1], test_images.shape[2])) 490 | result[result >= prob] = 1.0 491 | result[result < prob] = 0.0 492 | result = result.astype(np.float32) * 255. 493 | result = np.clip(result, 0, 255).astype('uint8') 494 | label = np.clip(label, 0, 255).astype('uint8') 495 | return result, label 496 | -------------------------------------------------------------------------------- /TNSCUI2020/Vnet2d/vnet_model.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | import cv2 4 | import numpy as np 5 | import tensorflow as tf 6 | 7 | from Vnet2d.layer import (conv2d, deconv2d, upsample2d, normalizationlayer, crop_and_concat, resnet_Add, 8 | weight_xavier_init, bias_variable) 9 | 10 | 11 | def conv_bn_relu_drop(x, kernalshape, phase, drop_conv, height=None, width=None, scope=None): 12 | with tf.name_scope(scope): 13 | W = weight_xavier_init(shape=kernalshape, n_inputs=kernalshape[0] * kernalshape[1] * kernalshape[2], 14 | n_outputs=kernalshape[-1], activefunction='relu', variable_name=str(scope) + 'W') 15 | B = bias_variable([kernalshape[-1]], variable_name=str(scope) + 'B') 16 | conv = conv2d(x, W) + B 17 | conv = normalizationlayer(conv, phase, height=height, width=width, norm_type='group', scope=scope) 18 | conv = tf.nn.dropout(tf.nn.relu(conv), drop_conv) 19 | return conv 20 | 21 | 22 | def down_sampling(x, kernalshape, phase, drop_conv, height=None, width=None, scope=None): 23 | with tf.name_scope(scope): 24 | W = weight_xavier_init(shape=kernalshape, n_inputs=kernalshape[0] * kernalshape[1] * kernalshape[2], 25 | n_outputs=kernalshape[-1], activefunction='relu', variable_name=str(scope) + 'W') 26 | B = bias_variable([kernalshape[-1]], variable_name=str(scope) + 'B') 27 | conv = conv2d(x, W, 2) + B 28 | conv = normalizationlayer(conv, phase, height=height, width=width, norm_type='group', scope=scope) 29 | conv = tf.nn.dropout(tf.nn.relu(conv), drop_conv) 30 | return conv 31 | 32 | 33 | def deconv_relu_drop(x, kernalshape, samefeture=False, scope=None): 34 | with tf.name_scope(scope): 35 | W = weight_xavier_init(shape=kernalshape, n_inputs=kernalshape[0] * kernalshape[1] * kernalshape[-1], 36 | n_outputs=kernalshape[-2], activefunction='relu', variable_name=str(scope) + 'W') 37 | B = bias_variable([kernalshape[-2]], variable_name=str(scope) + 'B') 38 | dconv = tf.nn.relu(deconv2d(x, W, samefeature=samefeture) + B) 39 | return dconv 40 | 41 | 42 | def conv_sigmod(x, kernalshape, scope=None): 43 | with tf.name_scope(scope): 44 | W = weight_xavier_init(shape=kernalshape, n_inputs=kernalshape[0] * kernalshape[1] * kernalshape[2], 45 | n_outputs=kernalshape[-1], activefunction='sigomd', variable_name=str(scope) + 'W') 46 | B = bias_variable([kernalshape[-1]], variable_name=str(scope) + 'B') 47 | conv = conv2d(x, W) + B 48 | conv = tf.nn.sigmoid(conv) 49 | return conv 50 | 51 | 52 | def conv_softmax(x, kernalshape, scope=None): 53 | with tf.name_scope(scope): 54 | W = weight_xavier_init(shape=kernalshape, n_inputs=kernalshape[0] * kernalshape[1] * kernalshape[2], 55 | n_outputs=kernalshape[-1], activefunction='sigomd', variable_name=str(scope) + 'W') 56 | B = bias_variable([kernalshape[-1]], variable_name=str(scope) + 'B') 57 | conv = conv2d(x, W) + B 58 | conv = tf.nn.softmax(conv) 59 | return conv 60 | 61 | 62 | def conv_relu(x, kernalshape, scope=None): 63 | with tf.name_scope(scope): 64 | W = weight_xavier_init(shape=kernalshape, n_inputs=kernalshape[0] * kernalshape[1] * kernalshape[2], 65 | n_outputs=kernalshape[-1], activefunction='relu', variable_name=str(scope) + 'W') 66 | B = bias_variable([kernalshape[-1]], variable_name=str(scope) + 'B') 67 | conv = conv2d(x, W) + B 68 | conv = tf.nn.relu(conv) 69 | return conv 70 | 71 | 72 | def _create_conv_net(X, image_width, image_height, image_channel, phase, drop_conv, n_class=1): 73 | inputX = tf.reshape(X, [-1, image_width, image_height, image_channel]) # shape=(?, 32, 32, 1) 74 | # VNet model 75 | # layer0->convolution 76 | layer0 = conv_relu(x=inputX, kernalshape=(3, 3, image_channel, 16), scope='layer0') 77 | # layer1->convolution 78 | layer1 = conv_bn_relu_drop(x=layer0, kernalshape=(3, 3, 16, 16), phase=phase, drop_conv=drop_conv, 79 | scope='layer1-1') 80 | layer1 = conv_bn_relu_drop(x=layer1, kernalshape=(3, 3, 16, 16), phase=phase, drop_conv=drop_conv, 81 | scope='layer1-2') 82 | layer1 = resnet_Add(x1=layer0, x2=layer1) 83 | # down sampling1 84 | down1 = down_sampling(x=layer1, kernalshape=(3, 3, 16, 32), phase=phase, drop_conv=drop_conv, scope='down1') 85 | # layer2->convolution 86 | layer2 = conv_bn_relu_drop(x=down1, kernalshape=(3, 3, 32, 32), phase=phase, drop_conv=drop_conv, 87 | scope='layer2_1') 88 | layer2 = conv_bn_relu_drop(x=layer2, kernalshape=(3, 3, 32, 32), phase=phase, drop_conv=drop_conv, 89 | scope='layer2_2') 90 | layer2 = resnet_Add(x1=down1, x2=layer2) 91 | # down sampling2 92 | down2 = down_sampling(x=layer2, kernalshape=(3, 3, 32, 64), phase=phase, drop_conv=drop_conv, scope='down2') 93 | # layer3->convolution 94 | layer3 = conv_bn_relu_drop(x=down2, kernalshape=(3, 3, 64, 64), phase=phase, drop_conv=drop_conv, 95 | scope='layer3_1') 96 | layer3 = conv_bn_relu_drop(x=layer3, kernalshape=(3, 3, 64, 64), phase=phase, drop_conv=drop_conv, 97 | scope='layer3_2') 98 | layer3 = conv_bn_relu_drop(x=layer3, kernalshape=(3, 3, 64, 64), phase=phase, drop_conv=drop_conv, 99 | scope='layer3_3') 100 | layer3 = resnet_Add(x1=down2, x2=layer3) 101 | # down sampling3 102 | down3 = down_sampling(x=layer3, kernalshape=(3, 3, 64, 128), phase=phase, drop_conv=drop_conv, scope='down3') 103 | # layer4->convolution 104 | layer4 = conv_bn_relu_drop(x=down3, kernalshape=(3, 3, 128, 128), phase=phase, drop_conv=drop_conv, 105 | scope='layer4_1') 106 | layer4 = conv_bn_relu_drop(x=layer4, kernalshape=(3, 3, 128, 128), phase=phase, drop_conv=drop_conv, 107 | scope='layer4_2') 108 | layer4 = conv_bn_relu_drop(x=layer4, kernalshape=(3, 3, 128, 128), phase=phase, drop_conv=drop_conv, 109 | scope='layer4_3') 110 | layer4 = resnet_Add(x1=down3, x2=layer4) 111 | # down sampling4 112 | down4 = down_sampling(x=layer4, kernalshape=(3, 3, 128, 256), phase=phase, drop_conv=drop_conv, scope='down4') 113 | # layer5->convolution 114 | layer5 = conv_bn_relu_drop(x=down4, kernalshape=(3, 3, 256, 256), phase=phase, drop_conv=drop_conv, 115 | scope='layer5_1') 116 | layer5 = conv_bn_relu_drop(x=layer5, kernalshape=(3, 3, 256, 256), phase=phase, drop_conv=drop_conv, 117 | scope='layer5_2') 118 | layer5 = conv_bn_relu_drop(x=layer5, kernalshape=(3, 3, 256, 256), phase=phase, drop_conv=drop_conv, 119 | scope='layer5_3') 120 | layer5 = resnet_Add(x1=down4, x2=layer5) 121 | # down sampling5 122 | down5 = down_sampling(x=layer5, kernalshape=(3, 3, 256, 512), phase=phase, drop_conv=drop_conv, scope='down5') 123 | # layer6->convolution 124 | layer6 = conv_bn_relu_drop(x=down5, kernalshape=(3, 3, 512, 512), phase=phase, drop_conv=drop_conv, 125 | scope='layer6_1') 126 | layer6 = conv_bn_relu_drop(x=layer6, kernalshape=(3, 3, 512, 512), phase=phase, drop_conv=drop_conv, 127 | scope='layer6_2') 128 | layer6 = conv_bn_relu_drop(x=layer6, kernalshape=(3, 3, 512, 512), phase=phase, drop_conv=drop_conv, 129 | scope='layer6_3') 130 | layer6 = resnet_Add(x1=down5, x2=layer6) 131 | # layer7->deconvolution 132 | deconv1 = deconv_relu_drop(x=layer6, kernalshape=(3, 3, 256, 512), scope='deconv1') 133 | # layer8->convolution 134 | layer7 = crop_and_concat(layer5, deconv1) 135 | _, H, W, _ = layer5.get_shape().as_list() 136 | layer7 = conv_bn_relu_drop(x=layer7, kernalshape=(3, 3, 512, 256), height=H, width=W, phase=phase, 137 | drop_conv=drop_conv, scope='layer7_1') 138 | layer7 = conv_bn_relu_drop(x=layer7, kernalshape=(3, 3, 256, 256), height=H, width=W, phase=phase, 139 | drop_conv=drop_conv, scope='layer7_2') 140 | layer7 = conv_bn_relu_drop(x=layer7, kernalshape=(3, 3, 256, 256), height=H, width=W, phase=phase, 141 | drop_conv=drop_conv, scope='layer7_3') 142 | layer7 = resnet_Add(x1=deconv1, x2=layer7) 143 | # deepspu1 144 | output_map1 = upsample2d(x=layer7, scale_factor=16, scope="upsample3d_1") 145 | output_map1 = conv_sigmod(x=output_map1, kernalshape=(1, 1, 256, n_class), scope='output_map1') 146 | # layer9->deconvolution 147 | deconv2 = deconv_relu_drop(x=layer7, kernalshape=(3, 3, 128, 256), scope='deconv2') 148 | # layer8->convolution 149 | layer8 = crop_and_concat(layer4, deconv2) 150 | _, H, W, _ = layer4.get_shape().as_list() 151 | layer8 = conv_bn_relu_drop(x=layer8, kernalshape=(3, 3, 256, 128), height=H, width=W, phase=phase, 152 | drop_conv=drop_conv, scope='layer8_1') 153 | layer8 = conv_bn_relu_drop(x=layer8, kernalshape=(3, 3, 128, 128), height=H, width=W, phase=phase, 154 | drop_conv=drop_conv, scope='layer8_2') 155 | layer8 = conv_bn_relu_drop(x=layer8, kernalshape=(3, 3, 128, 128), height=H, width=W, phase=phase, 156 | drop_conv=drop_conv, scope='layer8_3') 157 | layer8 = resnet_Add(x1=deconv2, x2=layer8) 158 | # deepspu2 159 | output_map2 = upsample2d(x=layer8, scale_factor=8, scope="upsample3d_2") 160 | output_map2 = conv_sigmod(x=output_map2, kernalshape=(1, 1, 128, n_class), scope='output_map2') 161 | # layer9->deconvolution 162 | deconv3 = deconv_relu_drop(x=layer8, kernalshape=(3, 3, 64, 128), scope='deconv3') 163 | # layer8->convolution 164 | layer9 = crop_and_concat(layer3, deconv3) 165 | _, H, W, _ = layer3.get_shape().as_list() 166 | layer9 = conv_bn_relu_drop(x=layer9, kernalshape=(3, 3, 128, 64), height=H, width=W, phase=phase, 167 | drop_conv=drop_conv, scope='layer9_1') 168 | layer9 = conv_bn_relu_drop(x=layer9, kernalshape=(3, 3, 64, 64), height=H, width=W, phase=phase, 169 | drop_conv=drop_conv, scope='layer9_2') 170 | layer9 = conv_bn_relu_drop(x=layer9, kernalshape=(3, 3, 64, 64), height=H, width=W, phase=phase, 171 | drop_conv=drop_conv, scope='layer9_3') 172 | layer9 = resnet_Add(x1=deconv3, x2=layer9) 173 | # deepspu3 174 | output_map3 = upsample2d(x=layer9, scale_factor=4, scope="upsample3d_3") 175 | output_map3 = conv_sigmod(x=output_map3, kernalshape=(1, 1, 64, n_class), scope='output_map3') 176 | # layer9->deconvolution 177 | deconv4 = deconv_relu_drop(x=layer9, kernalshape=(3, 3, 32, 64), scope='deconv4') 178 | # layer8->convolution 179 | layer10 = crop_and_concat(layer2, deconv4) 180 | _, H, W, _ = layer2.get_shape().as_list() 181 | layer10 = conv_bn_relu_drop(x=layer10, kernalshape=(3, 3, 64, 32), height=H, width=W, phase=phase, 182 | drop_conv=drop_conv, scope='layer10_1') 183 | layer10 = conv_bn_relu_drop(x=layer10, kernalshape=(3, 3, 32, 32), height=H, width=W, phase=phase, 184 | drop_conv=drop_conv, scope='layer10_2') 185 | layer10 = resnet_Add(x1=deconv4, x2=layer10) 186 | # deepspu4 187 | output_map4 = upsample2d(x=layer10, scale_factor=2, scope="upsample3d_4") 188 | output_map4 = conv_sigmod(x=output_map4, kernalshape=(1, 1, 32, n_class), scope='output_map4') 189 | # layer9->deconvolution 190 | deconv5 = deconv_relu_drop(x=layer10, kernalshape=(3, 3, 16, 32), scope='deconv5') 191 | # layer8->convolution 192 | layer11 = crop_and_concat(layer1, deconv5) 193 | _, H, W, _ = layer1.get_shape().as_list() 194 | layer11 = conv_bn_relu_drop(x=layer11, kernalshape=(3, 3, 32, 16), height=H, width=W, phase=phase, 195 | drop_conv=drop_conv, scope='layer11_1') 196 | layer11 = conv_bn_relu_drop(x=layer11, kernalshape=(3, 3, 16, 16), height=H, width=W, phase=phase, 197 | drop_conv=drop_conv, scope='layer11_2') 198 | layer11 = resnet_Add(x1=deconv5, x2=layer11) 199 | # layer14->output 200 | output_map = conv_sigmod(x=layer11, kernalshape=(1, 1, 16, n_class), scope='output') 201 | return output_map, output_map1, output_map2, output_map3, output_map4 202 | 203 | 204 | def _next_batch(train_images, train_labels, batch_size, index_in_epoch): 205 | start = index_in_epoch 206 | index_in_epoch += batch_size 207 | 208 | num_examples = train_images.shape[0] 209 | # when all trainig data have been already used, it is reorder randomly 210 | if index_in_epoch > num_examples: 211 | # shuffle the data 212 | perm = np.arange(num_examples) 213 | np.random.shuffle(perm) 214 | train_images = train_images[perm] 215 | train_labels = train_labels[perm] 216 | # start next epoch 217 | start = 0 218 | index_in_epoch = batch_size 219 | assert batch_size <= num_examples 220 | end = index_in_epoch 221 | return train_images[start:end], train_labels[start:end], index_in_epoch 222 | 223 | """ 224 | A DSVnet2d implementation 225 | 226 | :param image_height: number of height in the input image 227 | :param image_width: number of width in the input image 228 | :param channels: number of channels in the input image 229 | :param n_class: number of output labels 230 | :param costname: name of the cost function.Default is "cross_entropy" 231 | """ 232 | 233 | def __init__(self, image_height, image_width, channels=1, inference=False, model_path=None, 234 | costname="dice coefficient"): 235 | self.image_width = image_width 236 | self.image_height = image_height 237 | self.channels = channels 238 | 239 | self.X = tf.placeholder("float", shape=[None, image_height, image_width, channels], name="Input") 240 | self.Y_gt = tf.placeholder("float", shape=[None, image_height, image_width, channels], name="Output_GT") 241 | self.lr = tf.placeholder('float', name="Learning_rate") 242 | self.phase = tf.placeholder(tf.bool, name="Phase") 243 | self.drop_conv = tf.placeholder('float', name="DropOut") 244 | 245 | self.Y_pred, self.Y_pred1, self.Y_pred2, self.Y_pred3, self.Y_pred4 = _create_conv_net(self.X, self.image_width, 246 | self.image_height, 247 | self.channels, 248 | self.phase, 249 | self.drop_conv) 250 | self.alpha = 1 251 | # branch output 252 | self.cost0 = self.__get_cost(costname, self.Y_gt, self.Y_pred) 253 | self.cost1 = self.__get_cost(costname, self.Y_gt, self.Y_pred1) 254 | self.cost2 = self.__get_cost(costname, self.Y_gt, self.Y_pred2) 255 | self.cost3 = self.__get_cost(costname, self.Y_gt, self.Y_pred3) 256 | self.cost4 = self.__get_cost(costname, self.Y_gt, self.Y_pred4) 257 | # mixed branch 258 | self.mix_cost = self.__mixed_cost() 259 | # loss 260 | self.cost = self.cost0 + self.mix_cost 261 | self.accuracy = self.__get_accuracy(self.Y_gt, self.Y_pred) 262 | if inference: 263 | init = tf.global_variables_initializer() 264 | saver = tf.train.Saver() 265 | self.sess = tf.InteractiveSession() 266 | self.sess.run(init) 267 | saver.restore(self.sess, model_path) 268 | 269 | def __mixed_cost(self): 270 | loss = (self.cost1 + self.cost2 + self.cost3 + self.cost4) / 4. * self.alpha 271 | return loss 272 | 273 | def __get_cost(self, cost_name, Y_gt, Y_pred): 274 | H, W, C = Y_gt.get_shape().as_list()[1:] 275 | if cost_name == "dice coefficient": 276 | smooth = 1e-5 277 | pred_flat = tf.reshape(Y_pred, [-1, H * W * C]) 278 | true_flat = tf.reshape(Y_gt, [-1, H * W * C]) 279 | intersection = 2 * tf.reduce_sum(pred_flat * true_flat, axis=1) + smooth 280 | denominator = tf.reduce_sum(pred_flat, axis=1) + tf.reduce_sum(true_flat, axis=1) + smooth 281 | loss = -tf.reduce_mean(intersection / denominator) 282 | return loss 283 | if cost_name == "pixelwise_cross entroy": 284 | assert (C == 1) 285 | flat_logit = tf.reshape(Y_pred, [-1]) 286 | flat_label = tf.reshape(Y_gt, [-1]) 287 | loss = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits=flat_logit, labels=flat_label)) 288 | return loss 289 | 290 | def __get_accuracy(self, Y_gt, Y_pred, prob=0.8): 291 | """ 292 | binary iou 293 | :param Y_pred:A tensor resulting from a sigmod 294 | :param Y_gt:A tensor of the same shape as `output` 295 | :return: binary iou 296 | """ 297 | Y_pred_part = tf.to_float(Y_pred > prob) 298 | Y_pred_part = tf.cast(Y_pred_part, tf.float32) 299 | Y_gt_part = tf.identity(Y_gt) 300 | Y_gt_part = tf.cast(Y_gt_part, tf.float32) 301 | H, W, C = Y_gt.get_shape().as_list()[1:] 302 | smooth = 1.e-5 303 | smooth_tf = tf.constant(smooth, tf.float32) 304 | pred_flat = tf.reshape(Y_pred_part, [-1, H * W * C]) 305 | true_flat = tf.reshape(Y_gt_part, [-1, H * W * C]) 306 | intersection = tf.reduce_sum(pred_flat * true_flat, axis=-1) 307 | union = tf.reduce_sum(pred_flat, axis=-1) + tf.reduce_sum(true_flat, axis=-1) - intersection 308 | metric = tf.reduce_mean((intersection + smooth_tf) / (union + smooth_tf)) 309 | metric = tf.cond(tf.is_inf(metric), lambda: smooth_tf, lambda: metric) 310 | return metric 311 | 312 | def train(self, train_images, train_lanbels, model_name, logs_path, learning_rate, 313 | dropout_conv=0.5, train_epochs=10, batch_size=1): 314 | if not os.path.exists(logs_path): 315 | os.makedirs(logs_path) 316 | if not os.path.exists(logs_path + "model\\"): 317 | os.makedirs(logs_path + "model\\") 318 | model_path = logs_path + "model\\" + model_name 319 | train_op = tf.train.AdamOptimizer(self.lr).minimize(self.cost) 320 | 321 | init = tf.global_variables_initializer() 322 | saver = tf.train.Saver(tf.all_variables(), max_to_keep=10) 323 | 324 | tf.summary.scalar("loss", self.cost) 325 | tf.summary.scalar("accuracy", self.accuracy) 326 | merged_summary_op = tf.summary.merge_all() 327 | sess = tf.InteractiveSession(config=tf.ConfigProto(allow_soft_placement=True, log_device_placement=False)) 328 | summary_writer = tf.summary.FileWriter(logs_path, graph=tf.get_default_graph()) 329 | sess.run(init) 330 | 331 | DISPLAY_STEP = 1 332 | index_in_epoch = 0 333 | 334 | train_epochs = train_images.shape[0] * train_epochs 335 | for i in range(train_epochs): 336 | # get new batch 337 | batch_xs_path, batch_ys_path, index_in_epoch = _next_batch(train_images, train_lanbels, batch_size, 338 | index_in_epoch) 339 | batch_xs = np.empty((len(batch_xs_path), self.image_height, self.image_width, self.channels)) 340 | batch_ys = np.empty((len(batch_ys_path), self.image_height, self.image_width, self.channels)) 341 | 342 | for num in range(len(batch_xs_path)): 343 | image = cv2.imread(batch_xs_path[num], 0) 344 | label = cv2.imread(batch_ys_path[num], 0) 345 | image = cv2.resize(image, (self.image_width, self.image_height)) 346 | label = cv2.resize(label, (self.image_width, self.image_height)) 347 | batch_xs[num, :, :, :] = np.reshape(image, (self.image_height, self.image_width, self.channels)) 348 | batch_ys[num, :, :, :] = np.reshape(label, (self.image_height, self.image_width, self.channels)) 349 | # Extracting images and labels from given data 350 | batch_xs = batch_xs.astype(np.float) 351 | batch_ys = batch_ys.astype(np.float) 352 | # Normalize from [0:255] => [0.0:1.0] 353 | batch_xs = np.multiply(batch_xs, 1.0 / 255.0) 354 | batch_ys = np.multiply(batch_ys, 1.0 / 255.0) 355 | # check progress on every 1st,2nd,...,10th,20th,...,100th... step 356 | if i % DISPLAY_STEP == 0 or (i + 1) == train_epochs: 357 | train_loss, train_accuracy = sess.run([self.cost, self.accuracy], 358 | feed_dict={self.X: batch_xs, 359 | self.Y_gt: batch_ys, 360 | self.lr: learning_rate, 361 | self.phase: 1, 362 | self.drop_conv: dropout_conv}) 363 | pred = sess.run(self.Y_pred, feed_dict={self.X: batch_xs, 364 | self.Y_gt: batch_ys, 365 | self.phase: 1, 366 | self.drop_conv: 1}) 367 | result = np.reshape(pred[0], (self.image_height, self.image_width)) 368 | result = result.astype(np.float32) * 255. 369 | result = np.clip(result, 0, 255).astype('uint8') 370 | result_path = logs_path + 'result_%d_epoch.png' % (i) 371 | cv2.imwrite(result_path, result) 372 | true = np.reshape(batch_ys[0], (self.image_height, self.image_width)) 373 | true = true.astype(np.float32) * 255. 374 | true = np.clip(true, 0, 255).astype('uint8') 375 | true_path = logs_path + 'src_%d_epoch.png' % (i) 376 | cv2.imwrite(true_path, true) 377 | print('epochs %d training_loss ,Training_accuracy => %.5f,%.5f ' % (i, train_loss, train_accuracy)) 378 | save_path = saver.save(sess, model_path, global_step=i) 379 | print("Model saved in file:", save_path) 380 | if i % (DISPLAY_STEP * 10) == 0 and i: 381 | DISPLAY_STEP *= 10 382 | if i % 500 == 0 and i: 383 | self.alpha = self.alpha * 0.9 384 | # train on batch 385 | _, summary = sess.run([train_op, merged_summary_op], feed_dict={self.X: batch_xs, 386 | self.Y_gt: batch_ys, 387 | self.lr: learning_rate, 388 | self.phase: 1, 389 | self.drop_conv: dropout_conv}) 390 | summary_writer.add_summary(summary, i) 391 | summary_writer.close() 392 | save_path = saver.save(sess, model_path) 393 | print("Model saved in file:", save_path) 394 | 395 | def prediction(self, test_images): 396 | test_images = test_images.astype(np.float) 397 | # convert from [0:255] => [0.0:1.0] 398 | test_images = np.multiply(test_images, 1.0 / 255.0) 399 | test_images = np.reshape(test_images, (1, test_images.shape[0], test_images.shape[1], 1)) 400 | pred = self.sess.run(self.Y_pred, feed_dict={self.X: test_images, 401 | self.Y_gt: test_images, 402 | self.phase: 1, 403 | self.drop_conv: 1}) 404 | result = np.reshape(pred, (test_images.shape[1], test_images.shape[2])) 405 | result = result.astype(np.float32) * 255. 406 | result = np.clip(result, 0, 255).astype('uint8') 407 | return result 408 | 409 | 410 | class Vnet2dModule(object): 411 | """ 412 | A Vnet2d implementation 413 | 414 | :param image_height: number of height in the input image 415 | :param image_width: number of width in the input image 416 | :param channels: number of channels in the input image 417 | :param n_class: number of output labels 418 | :param costname: name of the cost function.Default is "cross_entropy" 419 | """ 420 | 421 | def __init__(self, image_height, image_width, channels=1, inference=False, model_path=None, 422 | costname="dice coefficient"): 423 | self.image_width = image_width 424 | self.image_height = image_height 425 | self.channels = channels 426 | self.alpha = 0.25 427 | self.gamma = 4 428 | 429 | self.X = tf.placeholder("float", shape=[None, image_height, image_width, channels], name="Input") 430 | self.Y_gt = tf.placeholder("float", shape=[None, image_height, image_width, channels], name="Output_GT") 431 | self.lr = tf.placeholder('float', name="Learning_rate") 432 | self.phase = tf.placeholder(tf.bool, name="Phase") 433 | self.drop_conv = tf.placeholder('float', name="DropOut") 434 | 435 | self.Y_pred, _, _, _, _ = _create_conv_net(self.X, self.image_width, 436 | self.image_height, 437 | self.channels, 438 | self.phase, 439 | self.drop_conv) 440 | self.cost = self.__get_cost(costname, self.Y_gt, self.Y_pred) 441 | self.accuracy = self.__get_accuracy(self.Y_gt, self.Y_pred) 442 | if inference: 443 | init = tf.global_variables_initializer() 444 | saver = tf.train.Saver() 445 | self.sess = tf.InteractiveSession() 446 | self.sess.run(init) 447 | saver.restore(self.sess, model_path) 448 | 449 | def __get_cost(self, cost_name, Y_gt, Y_pred): 450 | H, W, C = Y_gt.get_shape().as_list()[1:] 451 | if cost_name == "dice coefficient": 452 | smooth = 1e-5 453 | pred_flat = tf.reshape(Y_pred, [-1, H * W * C]) 454 | true_flat = tf.reshape(Y_gt, [-1, H * W * C]) 455 | intersection = 2 * tf.reduce_sum(pred_flat * true_flat, axis=1) + smooth 456 | denominator = tf.reduce_sum(pred_flat, axis=1) + tf.reduce_sum(true_flat, axis=1) + smooth 457 | loss = -tf.reduce_mean(intersection / denominator) 458 | return loss 459 | if cost_name == "pixelwise_cross entroy": 460 | assert (C == 1) 461 | flat_logit = tf.reshape(Y_pred, [-1]) 462 | flat_label = tf.reshape(Y_gt, [-1]) 463 | loss = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits=flat_logit, labels=flat_label)) 464 | return loss 465 | 466 | def __get_accuracy(self, Y_gt, Y_pred, prob=0.8): 467 | """ 468 | binary iou 469 | :param Y_pred:A tensor resulting from a sigmod 470 | :param Y_gt:A tensor of the same shape as `output` 471 | :return: binary iou 472 | """ 473 | Y_pred_part = tf.to_float(Y_pred > prob) 474 | Y_pred_part = tf.cast(Y_pred_part, tf.float32) 475 | Y_gt_part = tf.identity(Y_gt) 476 | Y_gt_part = tf.cast(Y_gt_part, tf.float32) 477 | H, W, C = Y_gt.get_shape().as_list()[1:] 478 | smooth = 1.e-5 479 | smooth_tf = tf.constant(smooth, tf.float32) 480 | pred_flat = tf.reshape(Y_pred_part, [-1, H * W * C]) 481 | true_flat = tf.reshape(Y_gt_part, [-1, H * W * C]) 482 | intersection = tf.reduce_sum(pred_flat * true_flat, axis=-1) 483 | union = tf.reduce_sum(pred_flat, axis=-1) + tf.reduce_sum(true_flat, axis=-1) - intersection 484 | metric = tf.reduce_mean((intersection + smooth_tf) / (union + smooth_tf)) 485 | metric = tf.cond(tf.is_inf(metric), lambda: smooth_tf, lambda: metric) 486 | return metric 487 | 488 | def train(self, train_images, train_lanbels, model_name, logs_path, learning_rate, 489 | dropout_conv=0.5, train_epochs=10, batch_size=1): 490 | if not os.path.exists(logs_path): 491 | os.makedirs(logs_path) 492 | if not os.path.exists(logs_path + "model\\"): 493 | os.makedirs(logs_path + "model\\") 494 | model_path = logs_path + "model\\" + model_name 495 | train_op = tf.train.AdamOptimizer(self.lr).minimize(self.cost) 496 | 497 | init = tf.global_variables_initializer() 498 | saver = tf.train.Saver(tf.all_variables(), max_to_keep=10) 499 | 500 | tf.summary.scalar("loss", self.cost) 501 | tf.summary.scalar("accuracy", self.accuracy) 502 | merged_summary_op = tf.summary.merge_all() 503 | sess = tf.InteractiveSession(config=tf.ConfigProto(allow_soft_placement=True, log_device_placement=False)) 504 | summary_writer = tf.summary.FileWriter(logs_path, graph=tf.get_default_graph()) 505 | sess.run(init) 506 | 507 | DISPLAY_STEP = 1 508 | index_in_epoch = 0 509 | 510 | train_epochs = train_images.shape[0] * train_epochs 511 | for i in range(train_epochs): 512 | # get new batch 513 | batch_xs_path, batch_ys_path, index_in_epoch = _next_batch(train_images, train_lanbels, batch_size, 514 | index_in_epoch) 515 | batch_xs = np.empty((len(batch_xs_path), self.image_height, self.image_width, self.channels)) 516 | batch_ys = np.empty((len(batch_ys_path), self.image_height, self.image_width, self.channels)) 517 | 518 | for num in range(len(batch_xs_path)): 519 | image = cv2.imread(batch_xs_path[num], 0) 520 | label = cv2.imread(batch_ys_path[num], 0) 521 | image = cv2.resize(image, (self.image_width, self.image_height)) 522 | label = cv2.resize(label, (self.image_width, self.image_height)) 523 | batch_xs[num, :, :, :] = np.reshape(image, (self.image_height, self.image_width, self.channels)) 524 | batch_ys[num, :, :, :] = np.reshape(label, (self.image_height, self.image_width, self.channels)) 525 | # Extracting images and labels from given data 526 | batch_xs = batch_xs.astype(np.float) 527 | batch_ys = batch_ys.astype(np.float) 528 | # Normalize from [0:255] => [0.0:1.0] 529 | batch_xs = np.multiply(batch_xs, 1.0 / 255.0) 530 | batch_ys = np.multiply(batch_ys, 1.0 / 255.0) 531 | # check progress on every 1st,2nd,...,10th,20th,...,100th... step 532 | if i % DISPLAY_STEP == 0 or (i + 1) == train_epochs: 533 | train_loss, train_accuracy = sess.run([self.cost, self.accuracy], 534 | feed_dict={self.X: batch_xs, 535 | self.Y_gt: batch_ys, 536 | self.lr: learning_rate, 537 | self.phase: 1, 538 | self.drop_conv: dropout_conv}) 539 | pred = sess.run(self.Y_pred, feed_dict={self.X: batch_xs, 540 | self.Y_gt: batch_ys, 541 | self.phase: 1, 542 | self.drop_conv: 1}) 543 | result = np.reshape(pred[0], (self.image_height, self.image_width)) 544 | result = result.astype(np.float32) * 255. 545 | result = np.clip(result, 0, 255).astype('uint8') 546 | result_path = logs_path + 'result_%d_epoch.png' % (i) 547 | cv2.imwrite(result_path, result) 548 | true = np.reshape(batch_ys[0], (self.image_height, self.image_width)) 549 | true = true.astype(np.float32) * 255. 550 | true = np.clip(true, 0, 255).astype('uint8') 551 | true_path = logs_path + 'src_%d_epoch.png' % (i) 552 | cv2.imwrite(true_path, true) 553 | print('epochs %d training_loss ,Training_accuracy => %.5f,%.5f ' % (i, train_loss, train_accuracy)) 554 | save_path = saver.save(sess, model_path, global_step=i) 555 | print("Model saved in file:", save_path) 556 | if i % (DISPLAY_STEP * 10) == 0 and i: 557 | DISPLAY_STEP *= 10 558 | # train on batch 559 | _, summary = sess.run([train_op, merged_summary_op], feed_dict={self.X: batch_xs, 560 | self.Y_gt: batch_ys, 561 | self.lr: learning_rate, 562 | self.phase: 1, 563 | self.drop_conv: dropout_conv}) 564 | summary_writer.add_summary(summary, i) 565 | summary_writer.close() 566 | save_path = saver.save(sess, model_path) 567 | print("Model saved in file:", save_path) 568 | 569 | def prediction(self, test_images): 570 | test_images = test_images.astype(np.float) 571 | test_images = np.reshape(test_images, (1, test_images.shape[0], test_images.shape[1], 1)) 572 | pred = self.sess.run(self.Y_pred, feed_dict={self.X: test_images, 573 | self.Y_gt: test_images, 574 | self.phase: 1, 575 | self.drop_conv: 1}) 576 | result = np.reshape(pred, (test_images.shape[1], test_images.shape[2])) 577 | result = result.astype(np.float32) * 255. 578 | result = np.clip(result, 0, 255).astype('uint8') 579 | return result 580 | --------------------------------------------------------------------------------