Last active
May 26, 2020 06:38
-
-
Save r1235613/e742cb9ea529cb0f7876bc470ef2eb6a to your computer and use it in GitHub Desktop.
segmentation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Python 3.7.7 (tags/v3.7.7:d7c567b08f, Mar 10 2020, 10:41:24) [MSC v.1900 64 bit (AMD64)] | |
Type 'copyright', 'credits' or 'license' for more information | |
IPython 7.14.0 -- An enhanced Interactive Python. Type '?' for help. | |
PyDev console: using IPython 7.14.0 | |
Python 3.7.7 (tags/v3.7.7:d7c567b08f, Mar 10 2020, 10:41:24) [MSC v.1900 64 bit (AMD64)] on win32 | |
runfile('E:/Python Project/cutpure/unet.py', wdir='E:/Python Project/cutpure') | |
2020-05-26 14:36:36.465555: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library cudart64_101.dll | |
2020-05-26 14:36:38.148867: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library nvcuda.dll | |
2020-05-26 14:36:38.218411: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1561] Found device 0 with properties: | |
pciBusID: 0000:02:00.0 name: GeForce GTX TITAN X computeCapability: 5.2 | |
coreClock: 1.076GHz coreCount: 24 deviceMemorySize: 12.00GiB deviceMemoryBandwidth: 313.37GiB/s | |
2020-05-26 14:36:38.219515: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1561] Found device 1 with properties: | |
pciBusID: 0000:01:00.0 name: GeForce GTX 1060 6GB computeCapability: 6.1 | |
coreClock: 1.7845GHz coreCount: 10 deviceMemorySize: 6.00GiB deviceMemoryBandwidth: 178.99GiB/s | |
2020-05-26 14:36:38.220200: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library cudart64_101.dll | |
2020-05-26 14:36:38.229238: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library cublas64_10.dll | |
2020-05-26 14:36:38.234360: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library cufft64_10.dll | |
2020-05-26 14:36:38.236227: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library curand64_10.dll | |
2020-05-26 14:36:38.242213: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library cusolver64_10.dll | |
2020-05-26 14:36:38.245179: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library cusparse64_10.dll | |
2020-05-26 14:36:38.268769: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library cudnn64_7.dll | |
2020-05-26 14:36:38.271627: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1703] Adding visible gpu devices: 0, 1 | |
2020-05-26 14:36:38.272123: I tensorflow/core/platform/cpu_feature_guard.cc:143] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 | |
2020-05-26 14:36:38.282981: I tensorflow/compiler/xla/service/service.cc:168] XLA service 0x214c4ff1ab0 initialized for platform Host (this does not guarantee that XLA will be used). Devices: | |
2020-05-26 14:36:38.283456: I tensorflow/compiler/xla/service/service.cc:176] StreamExecutor device (0): Host, Default Version | |
2020-05-26 14:36:38.527104: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1561] Found device 0 with properties: | |
pciBusID: 0000:02:00.0 name: GeForce GTX TITAN X computeCapability: 5.2 | |
coreClock: 1.076GHz coreCount: 24 deviceMemorySize: 12.00GiB deviceMemoryBandwidth: 313.37GiB/s | |
2020-05-26 14:36:38.527954: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1561] Found device 1 with properties: | |
pciBusID: 0000:01:00.0 name: GeForce GTX 1060 6GB computeCapability: 6.1 | |
coreClock: 1.7845GHz coreCount: 10 deviceMemorySize: 6.00GiB deviceMemoryBandwidth: 178.99GiB/s | |
2020-05-26 14:36:38.528450: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library cudart64_101.dll | |
2020-05-26 14:36:38.528696: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library cublas64_10.dll | |
2020-05-26 14:36:38.528946: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library cufft64_10.dll | |
2020-05-26 14:36:38.529182: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library curand64_10.dll | |
2020-05-26 14:36:38.529421: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library cusolver64_10.dll | |
2020-05-26 14:36:38.529671: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library cusparse64_10.dll | |
2020-05-26 14:36:38.529915: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library cudnn64_7.dll | |
2020-05-26 14:36:38.531428: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1703] Adding visible gpu devices: 0, 1 | |
2020-05-26 14:36:39.666541: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1102] Device interconnect StreamExecutor with strength 1 edge matrix: | |
2020-05-26 14:36:39.666826: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1108] 0 1 | |
2020-05-26 14:36:39.667005: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1121] 0: N N | |
2020-05-26 14:36:39.667163: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1121] 1: N N | |
2020-05-26 14:36:39.668828: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1247] Created TensorFlow device (/job:localhost/replica:0/task:0/device:GPU:0 with 9603 MB memory) -> physical GPU (device: 0, name: GeForce GTX TITAN X, pci bus id: 0000:02:00.0, compute capability: 5.2) | |
2020-05-26 14:36:39.670673: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1247] Created TensorFlow device (/job:localhost/replica:0/task:0/device:GPU:1 with 4700 MB memory) -> physical GPU (device: 1, name: GeForce GTX 1060 6GB, pci bus id: 0000:01:00.0, compute capability: 6.1) | |
2020-05-26 14:36:39.674100: I tensorflow/compiler/xla/service/service.cc:168] XLA service 0x214fb55c120 initialized for platform CUDA (this does not guarantee that XLA will be used). Devices: | |
2020-05-26 14:36:39.674575: I tensorflow/compiler/xla/service/service.cc:176] StreamExecutor device (0): GeForce GTX TITAN X, Compute Capability 5.2 | |
2020-05-26 14:36:39.674925: I tensorflow/compiler/xla/service/service.cc:176] StreamExecutor device (1): GeForce GTX 1060 6GB, Compute Capability 6.1 | |
Failed to import pydot. You must install pydot and graphviz for `pydotprint` to work. | |
images\03746.jpg | |
test_mask\03746.png | |
WARNING:tensorflow:Model was constructed with shape (None, 128, 128, 3) for input Tensor("input_2:0", shape=(None, 128, 128, 3), dtype=float32), but it was called on an input with incompatible shape (None, 1, 128, 128, 3). | |
WARNING:tensorflow:Model was constructed with shape (None, 128, 128, 3) for input Tensor("input_1:0", shape=(None, 128, 128, 3), dtype=float32), but it was called on an input with incompatible shape (None, 1, 128, 128, 3). | |
Traceback (most recent call last): | |
File "E:\Python Project\cutpure\venv\lib\site-packages\IPython\core\interactiveshell.py", line 3331, in run_code | |
exec(code_obj, self.user_global_ns, self.user_ns) | |
File "<ipython-input-2-7690f6e3019f>", line 1, in <module> | |
runfile('E:/Python Project/cutpure/unet.py', wdir='E:/Python Project/cutpure') | |
File "C:\Program Files\JetBrains\PyCharm 2020.1.1\plugins\python\helpers\pydev\_pydev_bundle\pydev_umd.py", line 197, in runfile | |
pydev_imports.execfile(filename, global_vars, local_vars) # execute the script | |
File "C:\Program Files\JetBrains\PyCharm 2020.1.1\plugins\python\helpers\pydev\_pydev_imps\_pydev_execfile.py", line 18, in execfile | |
exec(compile(contents+"\n", file, 'exec'), glob, loc) | |
File "E:/Python Project/cutpure/unet.py", line 116, in <module> | |
show_predictions() | |
File "E:/Python Project/cutpure/unet.py", line 112, in show_predictions | |
image[tf.newaxis, ...] | |
File "E:\Python Project\cutpure\venv\lib\site-packages\tensorflow\python\keras\engine\training.py", line 88, in _method_wrapper | |
return method(self, *args, **kwargs) | |
File "E:\Python Project\cutpure\venv\lib\site-packages\tensorflow\python\keras\engine\training.py", line 1268, in predict | |
tmp_batch_outputs = predict_function(iterator) | |
File "E:\Python Project\cutpure\venv\lib\site-packages\tensorflow\python\eager\def_function.py", line 580, in __call__ | |
result = self._call(*args, **kwds) | |
File "E:\Python Project\cutpure\venv\lib\site-packages\tensorflow\python\eager\def_function.py", line 627, in _call | |
self._initialize(args, kwds, add_initializers_to=initializers) | |
File "E:\Python Project\cutpure\venv\lib\site-packages\tensorflow\python\eager\def_function.py", line 506, in _initialize | |
*args, **kwds)) | |
File "E:\Python Project\cutpure\venv\lib\site-packages\tensorflow\python\eager\function.py", line 2446, in _get_concrete_function_internal_garbage_collected | |
graph_function, _, _ = self._maybe_define_function(args, kwargs) | |
File "E:\Python Project\cutpure\venv\lib\site-packages\tensorflow\python\eager\function.py", line 2777, in _maybe_define_function | |
graph_function = self._create_graph_function(args, kwargs) | |
File "E:\Python Project\cutpure\venv\lib\site-packages\tensorflow\python\eager\function.py", line 2667, in _create_graph_function | |
capture_by_value=self._capture_by_value), | |
File "E:\Python Project\cutpure\venv\lib\site-packages\tensorflow\python\framework\func_graph.py", line 981, in func_graph_from_py_func | |
func_outputs = python_func(*func_args, **func_kwargs) | |
File "E:\Python Project\cutpure\venv\lib\site-packages\tensorflow\python\eager\def_function.py", line 441, in wrapped_fn | |
return weak_wrapped_fn().__wrapped__(*args, **kwds) | |
File "E:\Python Project\cutpure\venv\lib\site-packages\tensorflow\python\framework\func_graph.py", line 968, in wrapper | |
raise e.ag_error_metadata.to_exception(e) | |
ValueError: in user code: | |
E:\Python Project\cutpure\venv\lib\site-packages\tensorflow\python\keras\engine\training.py:1147 predict_function * | |
outputs = self.distribute_strategy.run( | |
E:\Python Project\cutpure\venv\lib\site-packages\tensorflow\python\distribute\distribute_lib.py:951 run ** | |
return self._extended.call_for_each_replica(fn, args=args, kwargs=kwargs) | |
E:\Python Project\cutpure\venv\lib\site-packages\tensorflow\python\distribute\distribute_lib.py:2290 call_for_each_replica | |
return self._call_for_each_replica(fn, args, kwargs) | |
E:\Python Project\cutpure\venv\lib\site-packages\tensorflow\python\distribute\distribute_lib.py:2649 _call_for_each_replica | |
return fn(*args, **kwargs) | |
E:\Python Project\cutpure\venv\lib\site-packages\tensorflow\python\keras\engine\training.py:1122 predict_step ** | |
return self(x, training=False) | |
E:\Python Project\cutpure\venv\lib\site-packages\tensorflow\python\keras\engine\base_layer.py:927 __call__ | |
outputs = call_fn(cast_inputs, *args, **kwargs) | |
E:\Python Project\cutpure\venv\lib\site-packages\tensorflow\python\keras\engine\network.py:719 call | |
convert_kwargs_to_constants=base_layer_utils.call_context().saving) | |
E:\Python Project\cutpure\venv\lib\site-packages\tensorflow\python\keras\engine\network.py:888 _run_internal_graph | |
output_tensors = layer(computed_tensors, **kwargs) | |
E:\Python Project\cutpure\venv\lib\site-packages\tensorflow\python\keras\engine\base_layer.py:927 __call__ | |
outputs = call_fn(cast_inputs, *args, **kwargs) | |
E:\Python Project\cutpure\venv\lib\site-packages\tensorflow\python\keras\engine\network.py:719 call | |
convert_kwargs_to_constants=base_layer_utils.call_context().saving) | |
E:\Python Project\cutpure\venv\lib\site-packages\tensorflow\python\keras\engine\network.py:888 _run_internal_graph | |
output_tensors = layer(computed_tensors, **kwargs) | |
E:\Python Project\cutpure\venv\lib\site-packages\tensorflow\python\keras\engine\base_layer.py:886 __call__ | |
self.name) | |
E:\Python Project\cutpure\venv\lib\site-packages\tensorflow\python\keras\engine\input_spec.py:180 assert_input_compatibility | |
str(x.shape.as_list())) | |
ValueError: Input 0 of layer Conv1_pad is incompatible with the layer: expected ndim=4, found ndim=5. Full shape received: [None, 1, 128, 128, 3] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# image | |
(<tf.Tensor: shape=(128, 128, 3), dtype=float32, numpy= | |
array([[[0.34620097, 0.4560049 , 0.05784314], | |
[0.3140319 , 0.41991425, 0.0473652 ], | |
[0.28596815, 0.38670346, 0.04920343], | |
..., | |
[0.07720588, 0.10857843, 0.11642157], | |
[0.08112745, 0.10073529, 0.1125 ], | |
[0.08143383, 0.10104167, 0.11280637]], | |
[[0.38897058, 0.50661767, 0.06691177], | |
[0.36832106, 0.48204654, 0.0658701 ], | |
[0.37444854, 0.48725492, 0.07395834], | |
..., | |
[0.0872549 , 0.11862745, 0.1264706 ], | |
[0.09411765, 0.11372549, 0.1254902 ], | |
[0.10196079, 0.12156863, 0.13333334]], | |
[[0.40735295, 0.5289216 , 0.06568628], | |
[0.40128675, 0.52064955, 0.06844363], | |
[0.39227942, 0.50845593, 0.04889706], | |
..., | |
[0.08682598, 0.11819853, 0.12604168], | |
[0.09754902, 0.12230393, 0.13235295], | |
[0.1002451 , 0.125 , 0.13504903]], | |
..., | |
[[0.5556373 , 0.2723652 , 0.19368874], | |
[0.35618874, 0.12267157, 0.04993873], | |
[0.3194853 , 0.11035539, 0.05245098], | |
..., | |
[0.40269607, 0.4004902 , 0.43333334], | |
[0.39289218, 0.39803922, 0.43553925], | |
[0.3754902 , 0.38946077, 0.4247549 ]], | |
[[0.48719364, 0.20686275, 0.13474265], | |
[0.34515932, 0.11378676, 0.0588848 ], | |
[0.31862748, 0.11078431, 0.05588235], | |
..., | |
[0.40471816, 0.4007966 , 0.424326 ], | |
[0.4094363 , 0.4094363 , 0.44080883], | |
[0.38106617, 0.4026348 , 0.4261642 ]], | |
[[0.4417892 , 0.1584559 , 0.09963235], | |
[0.34901962, 0.11372549, 0.07450981], | |
[0.32156864, 0.11372549, 0.05882353], | |
..., | |
[0.41121325, 0.40729168, 0.4308211 ], | |
[0.40392157, 0.40784314, 0.42352942], | |
[0.40588236, 0.4284314 , 0.4392157 ]]], dtype=float32)>, | |
# mask | |
array([[0, 0, 0, ..., 0, 0, 0], | |
[0, 0, 0, ..., 0, 0, 0], | |
[0, 0, 0, ..., 0, 0, 0], | |
..., | |
[0, 0, 0, ..., 0, 0, 0], | |
[0, 0, 0, ..., 0, 0, 0], | |
[0, 0, 0, ..., 0, 0, 0]])) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import numpy as np | |
from PIL import Image | |
import tensorflow as tf | |
import pathlib | |
def f321(com: int): | |
if com == 0: | |
return 1 | |
elif com == 255: | |
return 0 | |
else: | |
return 2 | |
def image_label_4_u_net(src): | |
img = Image.open(src) | |
img = img.resize((128, 128), Image.ANTIALIAS) | |
data = np.asarray(img) | |
return np.asanyarray(list(map(lambda x: list(map(lambda y: f321(y), x)), data))) | |
def pic2array(src): | |
img = Image.open(src) | |
img = np.asarray(img) | |
img = tf.cast(img, tf.float32) / 255.0 | |
img = tf.image.resize(img, (128, 128)) | |
return np.array(img) | |
class LoadImages: | |
def __init__(self, mask_folder: pathlib.Path, ori_image_folder: pathlib.Path): | |
if not mask_folder.is_dir() or not ori_image_folder.is_dir(): | |
raise ValueError("輸入的路徑錯誤,需要一個資料夾") | |
self.folder = mask_folder | |
self.ori_image_folder = ori_image_folder | |
def __len__(self): | |
return len(list(self.folder.iterdir())) | |
def gen_image_data(self, only=None): | |
mask_paths = list(self.folder.iterdir()) | |
while len(mask_paths) != 0: | |
mask_path: pathlib.Path = mask_paths.pop() | |
ori_image_path: pathlib.Path = self.ori_image_folder / mask_path.name | |
ori_image_path = ori_image_path.with_suffix('.jpg') | |
print(str(ori_image_path)) | |
print(str(mask_path)) | |
if only == "mask": | |
yield image_label_4_u_net(mask_path) | |
elif only == "pic": | |
yield pic2array(ori_image_path) | |
else: | |
yield pic2array(ori_image_path), image_label_4_u_net(mask_path) | |
def get_all_data(self, only=None): | |
if only in ["mask", "pic"]: | |
return list(self.gen_image_data(only)) | |
else: | |
return list(self.gen_image_data("pic")), list(self.gen_image_data("mask")) | |
def f012_to_rgb(types): | |
if types == 0: | |
return [0.5, 0, 0] | |
elif types == 1: | |
return [0, 0.5, 0] | |
elif types == 2: | |
return [0, 0, 0.5] | |
else: | |
return [0, 0, 0] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Copyright 2019 The TensorFlow Authors. All Rights Reserved. | |
# | |
# Licensed under the Apache License, Version 2.0 (the "License"); | |
# you may not use this file except in compliance with the License. | |
# You may obtain a copy of the License at | |
# | |
# http://www.apache.org/licenses/LICENSE-2.0 | |
# | |
# Unless required by applicable law or agreed to in writing, software | |
# distributed under the License is distributed on an "AS IS" BASIS, | |
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
# See the License for the specific language governing permissions and | |
# limitations under the License. | |
# ============================================================================== | |
"""Pix2pix. | |
""" | |
from __future__ import absolute_import | |
from __future__ import division | |
from __future__ import print_function | |
import os | |
import time | |
from absl import app | |
from absl import flags | |
import tensorflow as tf | |
FLAGS = flags.FLAGS | |
flags.DEFINE_integer('buffer_size', 400, 'Shuffle buffer size') | |
flags.DEFINE_integer('batch_size', 1, 'Batch Size') | |
flags.DEFINE_integer('epochs', 1, 'Number of epochs') | |
flags.DEFINE_string('path', None, 'Path to the data folder') | |
flags.DEFINE_boolean('enable_function', True, 'Enable Function?') | |
IMG_WIDTH = 256 | |
IMG_HEIGHT = 256 | |
AUTOTUNE = tf.data.experimental.AUTOTUNE | |
def load(image_file): | |
"""Loads the image and generates input and target image. | |
Args: | |
image_file: .jpeg file | |
Returns: | |
Input image, target image | |
""" | |
image = tf.io.read_file(image_file) | |
image = tf.image.decode_jpeg(image) | |
w = tf.shape(image)[1] | |
w = w // 2 | |
real_image = image[:, :w, :] | |
input_image = image[:, w:, :] | |
input_image = tf.cast(input_image, tf.float32) | |
real_image = tf.cast(real_image, tf.float32) | |
return input_image, real_image | |
def resize(input_image, real_image, height, width): | |
input_image = tf.image.resize(input_image, [height, width], | |
method=tf.image.ResizeMethod.NEAREST_NEIGHBOR) | |
real_image = tf.image.resize(real_image, [height, width], | |
method=tf.image.ResizeMethod.NEAREST_NEIGHBOR) | |
return input_image, real_image | |
def random_crop(input_image, real_image): | |
stacked_image = tf.stack([input_image, real_image], axis=0) | |
cropped_image = tf.image.random_crop( | |
stacked_image, size=[2, IMG_HEIGHT, IMG_WIDTH, 3]) | |
return cropped_image[0], cropped_image[1] | |
def normalize(input_image, real_image): | |
input_image = (input_image / 127.5) - 1 | |
real_image = (real_image / 127.5) - 1 | |
return input_image, real_image | |
@tf.function | |
def random_jitter(input_image, real_image): | |
"""Random jittering. | |
Resizes to 286 x 286 and then randomly crops to IMG_HEIGHT x IMG_WIDTH. | |
Args: | |
input_image: Input Image | |
real_image: Real Image | |
Returns: | |
Input Image, real image | |
""" | |
# resizing to 286 x 286 x 3 | |
input_image, real_image = resize(input_image, real_image, 286, 286) | |
# randomly cropping to 256 x 256 x 3 | |
input_image, real_image = random_crop(input_image, real_image) | |
if tf.random.uniform(()) > 0.5: | |
# random mirroring | |
input_image = tf.image.flip_left_right(input_image) | |
real_image = tf.image.flip_left_right(real_image) | |
return input_image, real_image | |
def load_image_train(image_file): | |
input_image, real_image = load(image_file) | |
input_image, real_image = random_jitter(input_image, real_image) | |
input_image, real_image = normalize(input_image, real_image) | |
return input_image, real_image | |
def load_image_test(image_file): | |
input_image, real_image = load(image_file) | |
input_image, real_image = resize(input_image, real_image, | |
IMG_HEIGHT, IMG_WIDTH) | |
input_image, real_image = normalize(input_image, real_image) | |
return input_image, real_image | |
def create_dataset(path_to_train_images, path_to_test_images, buffer_size, | |
batch_size): | |
"""Creates a tf.data Dataset. | |
Args: | |
path_to_train_images: Path to train images folder. | |
path_to_test_images: Path to test images folder. | |
buffer_size: Shuffle buffer size. | |
batch_size: Batch size | |
Returns: | |
train dataset, test dataset | |
""" | |
train_dataset = tf.data.Dataset.list_files(path_to_train_images) | |
train_dataset = train_dataset.shuffle(buffer_size) | |
train_dataset = train_dataset.map( | |
load_image_train, num_parallel_calls=AUTOTUNE) | |
train_dataset = train_dataset.batch(batch_size) | |
test_dataset = tf.data.Dataset.list_files(path_to_test_images) | |
test_dataset = test_dataset.map( | |
load_image_test, num_parallel_calls=AUTOTUNE) | |
test_dataset = test_dataset.batch(batch_size) | |
return train_dataset, test_dataset | |
class InstanceNormalization(tf.keras.layers.Layer): | |
"""Instance Normalization Layer (https://arxiv.org/abs/1607.08022).""" | |
def __init__(self, epsilon=1e-5): | |
super(InstanceNormalization, self).__init__() | |
self.epsilon = epsilon | |
def build(self, input_shape): | |
self.scale = self.add_weight( | |
name='scale', | |
shape=input_shape[-1:], | |
initializer=tf.random_normal_initializer(1., 0.02), | |
trainable=True) | |
self.offset = self.add_weight( | |
name='offset', | |
shape=input_shape[-1:], | |
initializer='zeros', | |
trainable=True) | |
def call(self, x): | |
mean, variance = tf.nn.moments(x, axes=[1, 2], keepdims=True) | |
inv = tf.math.rsqrt(variance + self.epsilon) | |
normalized = (x - mean) * inv | |
return self.scale * normalized + self.offset | |
def downsample(filters, size, norm_type='batchnorm', apply_norm=True): | |
"""Downsamples an input. | |
Conv2D => Batchnorm => LeakyRelu | |
Args: | |
filters: number of filters | |
size: filter size | |
norm_type: Normalization type; either 'batchnorm' or 'instancenorm'. | |
apply_norm: If True, adds the batchnorm layer | |
Returns: | |
Downsample Sequential Model | |
""" | |
initializer = tf.random_normal_initializer(0., 0.02) | |
result = tf.keras.Sequential() | |
result.add( | |
tf.keras.layers.Conv2D(filters, size, strides=2, padding='same', | |
kernel_initializer=initializer, use_bias=False)) | |
if apply_norm: | |
if norm_type.lower() == 'batchnorm': | |
result.add(tf.keras.layers.BatchNormalization()) | |
elif norm_type.lower() == 'instancenorm': | |
result.add(InstanceNormalization()) | |
result.add(tf.keras.layers.LeakyReLU()) | |
return result | |
def upsample(filters, size, norm_type='batchnorm', apply_dropout=False): | |
"""Upsamples an input. | |
Conv2DTranspose => Batchnorm => Dropout => Relu | |
Args: | |
filters: number of filters | |
size: filter size | |
norm_type: Normalization type; either 'batchnorm' or 'instancenorm'. | |
apply_dropout: If True, adds the dropout layer | |
Returns: | |
Upsample Sequential Model | |
""" | |
initializer = tf.random_normal_initializer(0., 0.02) | |
result = tf.keras.Sequential() | |
result.add( | |
tf.keras.layers.Conv2DTranspose(filters, size, strides=2, | |
padding='same', | |
kernel_initializer=initializer, | |
use_bias=False)) | |
if norm_type.lower() == 'batchnorm': | |
result.add(tf.keras.layers.BatchNormalization()) | |
elif norm_type.lower() == 'instancenorm': | |
result.add(InstanceNormalization()) | |
if apply_dropout: | |
result.add(tf.keras.layers.Dropout(0.5)) | |
result.add(tf.keras.layers.ReLU()) | |
return result | |
def unet_generator(output_channels, norm_type='batchnorm'): | |
"""Modified u-net generator model (https://arxiv.org/abs/1611.07004). | |
Args: | |
output_channels: Output channels | |
norm_type: Type of normalization. Either 'batchnorm' or 'instancenorm'. | |
Returns: | |
Generator model | |
""" | |
down_stack = [ | |
downsample(64, 4, norm_type, apply_norm=False), # (bs, 128, 128, 64) | |
downsample(128, 4, norm_type), # (bs, 64, 64, 128) | |
downsample(256, 4, norm_type), # (bs, 32, 32, 256) | |
downsample(512, 4, norm_type), # (bs, 16, 16, 512) | |
downsample(512, 4, norm_type), # (bs, 8, 8, 512) | |
downsample(512, 4, norm_type), # (bs, 4, 4, 512) | |
downsample(512, 4, norm_type), # (bs, 2, 2, 512) | |
downsample(512, 4, norm_type), # (bs, 1, 1, 512) | |
] | |
up_stack = [ | |
upsample(512, 4, norm_type, apply_dropout=True), # (bs, 2, 2, 1024) | |
upsample(512, 4, norm_type, apply_dropout=True), # (bs, 4, 4, 1024) | |
upsample(512, 4, norm_type, apply_dropout=True), # (bs, 8, 8, 1024) | |
upsample(512, 4, norm_type), # (bs, 16, 16, 1024) | |
upsample(256, 4, norm_type), # (bs, 32, 32, 512) | |
upsample(128, 4, norm_type), # (bs, 64, 64, 256) | |
upsample(64, 4, norm_type), # (bs, 128, 128, 128) | |
] | |
initializer = tf.random_normal_initializer(0., 0.02) | |
last = tf.keras.layers.Conv2DTranspose( | |
output_channels, 4, strides=2, | |
padding='same', kernel_initializer=initializer, | |
activation='tanh') # (bs, 256, 256, 3) | |
concat = tf.keras.layers.Concatenate() | |
inputs = tf.keras.layers.Input(shape=[None, None, 3]) | |
x = inputs | |
# Downsampling through the model | |
skips = [] | |
for down in down_stack: | |
x = down(x) | |
skips.append(x) | |
skips = reversed(skips[:-1]) | |
# Upsampling and establishing the skip connections | |
for up, skip in zip(up_stack, skips): | |
x = up(x) | |
x = concat([x, skip]) | |
x = last(x) | |
return tf.keras.Model(inputs=inputs, outputs=x) | |
def discriminator(norm_type='batchnorm', target=True): | |
"""PatchGan discriminator model (https://arxiv.org/abs/1611.07004). | |
Args: | |
norm_type: Type of normalization. Either 'batchnorm' or 'instancenorm'. | |
target: Bool, indicating whether target image is an input or not. | |
Returns: | |
Discriminator model | |
""" | |
initializer = tf.random_normal_initializer(0., 0.02) | |
inp = tf.keras.layers.Input(shape=[None, None, 3], name='input_image') | |
x = inp | |
if target: | |
tar = tf.keras.layers.Input(shape=[None, None, 3], name='target_image') | |
x = tf.keras.layers.concatenate([inp, tar]) # (bs, 256, 256, channels*2) | |
down1 = downsample(64, 4, norm_type, False)(x) # (bs, 128, 128, 64) | |
down2 = downsample(128, 4, norm_type)(down1) # (bs, 64, 64, 128) | |
down3 = downsample(256, 4, norm_type)(down2) # (bs, 32, 32, 256) | |
zero_pad1 = tf.keras.layers.ZeroPadding2D()(down3) # (bs, 34, 34, 256) | |
conv = tf.keras.layers.Conv2D( | |
512, 4, strides=1, kernel_initializer=initializer, | |
use_bias=False)(zero_pad1) # (bs, 31, 31, 512) | |
if norm_type.lower() == 'batchnorm': | |
norm1 = tf.keras.layers.BatchNormalization()(conv) | |
elif norm_type.lower() == 'instancenorm': | |
norm1 = InstanceNormalization()(conv) | |
leaky_relu = tf.keras.layers.LeakyReLU()(norm1) | |
zero_pad2 = tf.keras.layers.ZeroPadding2D()(leaky_relu) # (bs, 33, 33, 512) | |
last = tf.keras.layers.Conv2D( | |
1, 4, strides=1, | |
kernel_initializer=initializer)(zero_pad2) # (bs, 30, 30, 1) | |
if target: | |
return tf.keras.Model(inputs=[inp, tar], outputs=last) | |
else: | |
return tf.keras.Model(inputs=inp, outputs=last) | |
def get_checkpoint_prefix(): | |
checkpoint_dir = './training_checkpoints' | |
checkpoint_prefix = os.path.join(checkpoint_dir, 'ckpt') | |
return checkpoint_prefix | |
class Pix2pix(object): | |
"""Pix2pix class. | |
Args: | |
epochs: Number of epochs. | |
enable_function: If true, train step is decorated with tf.function. | |
buffer_size: Shuffle buffer size.. | |
batch_size: Batch size. | |
""" | |
def __init__(self, epochs, enable_function): | |
self.epochs = epochs | |
self.enable_function = enable_function | |
self.lambda_value = 100 | |
self.loss_object = tf.keras.losses.BinaryCrossentropy(from_logits=True) | |
self.generator_optimizer = tf.keras.optimizers.Adam(2e-4, beta_1=0.5) | |
self.discriminator_optimizer = tf.keras.optimizers.Adam(2e-4, beta_1=0.5) | |
self.generator = unet_generator(output_channels=3) | |
self.discriminator = discriminator() | |
self.checkpoint = tf.train.Checkpoint( | |
generator_optimizer=self.generator_optimizer, | |
discriminator_optimizer=self.discriminator_optimizer, | |
generator=self.generator, | |
discriminator=self.discriminator) | |
def discriminator_loss(self, disc_real_output, disc_generated_output): | |
real_loss = self.loss_object( | |
tf.ones_like(disc_real_output), disc_real_output) | |
generated_loss = self.loss_object(tf.zeros_like( | |
disc_generated_output), disc_generated_output) | |
total_disc_loss = real_loss + generated_loss | |
return total_disc_loss | |
def generator_loss(self, disc_generated_output, gen_output, target): | |
gan_loss = self.loss_object(tf.ones_like( | |
disc_generated_output), disc_generated_output) | |
# mean absolute error | |
l1_loss = tf.reduce_mean(tf.abs(target - gen_output)) | |
total_gen_loss = gan_loss + (self.lambda_value * l1_loss) | |
return total_gen_loss | |
def train_step(self, input_image, target_image): | |
"""One train step over the generator and discriminator model. | |
Args: | |
input_image: Input Image. | |
target_image: Target image. | |
Returns: | |
generator loss, discriminator loss. | |
""" | |
with tf.GradientTape() as gen_tape, tf.GradientTape() as disc_tape: | |
gen_output = self.generator(input_image, training=True) | |
disc_real_output = self.discriminator( | |
[input_image, target_image], training=True) | |
disc_generated_output = self.discriminator( | |
[input_image, gen_output], training=True) | |
gen_loss = self.generator_loss( | |
disc_generated_output, gen_output, target_image) | |
disc_loss = self.discriminator_loss( | |
disc_real_output, disc_generated_output) | |
generator_gradients = gen_tape.gradient( | |
gen_loss, self.generator.trainable_variables) | |
discriminator_gradients = disc_tape.gradient( | |
disc_loss, self.discriminator.trainable_variables) | |
self.generator_optimizer.apply_gradients(zip( | |
generator_gradients, self.generator.trainable_variables)) | |
self.discriminator_optimizer.apply_gradients(zip( | |
discriminator_gradients, self.discriminator.trainable_variables)) | |
return gen_loss, disc_loss | |
def train(self, dataset, checkpoint_pr): | |
"""Train the GAN for x number of epochs. | |
Args: | |
dataset: train dataset. | |
checkpoint_pr: prefix in which the checkpoints are stored. | |
Returns: | |
Time for each epoch. | |
""" | |
time_list = [] | |
if self.enable_function: | |
self.train_step = tf.function(self.train_step) | |
for epoch in range(self.epochs): | |
start_time = time.time() | |
for input_image, target_image in dataset: | |
gen_loss, disc_loss = self.train_step(input_image, target_image) | |
wall_time_sec = time.time() - start_time | |
time_list.append(wall_time_sec) | |
# saving (checkpoint) the model every 20 epochs | |
if (epoch + 1) % 20 == 0: | |
self.checkpoint.save(file_prefix=checkpoint_pr) | |
template = 'Epoch {}, Generator loss {}, Discriminator Loss {}' | |
print (template.format(epoch, gen_loss, disc_loss)) | |
return time_list | |
def run_main(argv): | |
del argv | |
kwargs = {'epochs': FLAGS.epochs, 'enable_function': FLAGS.enable_function, | |
'path': FLAGS.path, 'buffer_size': FLAGS.buffer_size, | |
'batch_size': FLAGS.batch_size} | |
main(**kwargs) | |
def main(epochs, enable_function, path, buffer_size, batch_size): | |
path_to_folder = path | |
pix2pix_object = Pix2pix(epochs, enable_function) | |
train_dataset, _ = create_dataset( | |
os.path.join(path_to_folder, 'train/*.jpg'), | |
os.path.join(path_to_folder, 'test/*.jpg'), | |
buffer_size, batch_size) | |
checkpoint_pr = get_checkpoint_prefix() | |
print ('Training ...') | |
return pix2pix_object.train(train_dataset, checkpoint_pr) | |
if __name__ == '__main__': | |
app.run(run_main) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from __future__ import absolute_import, division, print_function, unicode_literals | |
import tensorflow as tf | |
from pic_func import LoadImages, f012_to_rgb | |
import pathlib | |
import pix2pix | |
from IPython.display import clear_output | |
import matplotlib.pyplot as plt | |
def display(display_list): | |
plt.figure(figsize=(15, 15)) | |
title = ['Input Image', 'True Mask', 'Predicted Mask'] | |
for i in range(len(display_list)): | |
plt.subplot(1, len(display_list), i + 1) | |
plt.title(title[i]) | |
# print(display_list[i]) | |
plt.imshow(tf.keras.preprocessing.image.array_to_img(display_list[i])) | |
plt.axis('off') | |
plt.show() | |
ori_images_dir = pathlib.Path('images') | |
train = LoadImages(pathlib.Path('train_mask'), ori_images_dir) | |
test = LoadImages(pathlib.Path('test_mask'), ori_images_dir) | |
TRAIN_LENGTH = len(train) | |
BATCH_SIZE = 32 | |
BUFFER_SIZE = 1000 | |
STEPS_PER_EPOCH = TRAIN_LENGTH // BATCH_SIZE | |
# 定義模型 | |
OUTPUT_CHANNELS = 3 | |
base_model = tf.keras.applications.MobileNetV2(input_shape=[128, 128, 3], include_top=False) | |
layer_names = [ | |
'block_1_expand_relu', # 64x64 | |
'block_3_expand_relu', # 32x32 | |
'block_6_expand_relu', # 16x16 | |
'block_13_expand_relu', # 8x8 | |
'block_16_project', # 4x4 | |
] | |
layers = [base_model.get_layer(name).output for name in layer_names] | |
# 创建特征提取模型 | |
down_stack = tf.keras.Model(inputs=base_model.input, outputs=layers) | |
down_stack.trainable = False | |
up_stack = [ | |
pix2pix.upsample(512, 3), # 4x4 -> 8x8 | |
pix2pix.upsample(256, 3), # 8x8 -> 16x16 | |
pix2pix.upsample(128, 3), # 16x16 -> 32x32 | |
pix2pix.upsample(64, 3), # 32x32 -> 64x64 | |
] | |
def unet_model(output_channels): | |
# 这是模型的最后一层 | |
inputs = tf.keras.layers.Input(shape=[128, 128, 3]) | |
x = inputs | |
# Downsampling through the model | |
skips = down_stack(x) | |
x = skips[-1] | |
skips = reversed(skips[:-1]) | |
# Upsampling and establishing the skip connections | |
for up, skip in zip(up_stack, skips): | |
x = up(x) | |
concat = tf.keras.layers.Concatenate() | |
x = concat([x, skip]) | |
# This is the last layer of the model | |
last = tf.keras.layers.Conv2DTranspose( | |
output_channels, 3, strides=2, | |
padding='same') # 64x64 -> 128x128 | |
x = last(x) | |
return tf.keras.Model(inputs=inputs, outputs=x) | |
model = unet_model(OUTPUT_CHANNELS) | |
model.compile(optimizer='adam', | |
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True), | |
metrics=['accuracy']) | |
tf.keras.utils.plot_model(model, show_shapes=True) | |
def create_mask(pred_mask): | |
pred_mask = tf.argmax(pred_mask, axis=-1) | |
pred_mask = pred_mask[..., tf.newaxis] | |
return pred_mask[0] | |
EPOCHS = 20 | |
VAL_SUBSPLITS = 5 | |
VALIDATION_STEPS = len(test) // BATCH_SIZE // VAL_SUBSPLITS | |
def show_predictions(dataset=test, num=1): | |
gen = dataset.gen_image_data() | |
for i in range(num): | |
image, mask = gen.__next__() | |
display([ | |
image, | |
list(map(lambda row: list(map(lambda cell: f012_to_rgb(cell), row)), mask)), | |
create_mask( | |
model.predict( | |
image[tf.newaxis, ...] | |
)) | |
]) | |
show_predictions() | |
class DisplayCallback(tf.keras.callbacks.Callback): | |
def on_epoch_end(self, epoch, logs=None): | |
clear_output(wait=True) | |
show_predictions() | |
print('\nSample Prediction after epoch {}\n'.format(epoch + 1)) | |
model_history = model.fit(train.gen_image_data(), | |
epochs=EPOCHS, | |
steps_per_epoch=STEPS_PER_EPOCH, | |
batch_size=BATCH_SIZE, | |
validation_steps=VALIDATION_STEPS, | |
validation_data=(test.gen_image_data()), | |
callbacks=[DisplayCallback()]) | |
loss = model_history.history['loss'] | |
val_loss = model_history.history['val_loss'] | |
epochs = range(EPOCHS) | |
plt.figure() | |
plt.plot(epochs, loss, 'r', label='Training loss') | |
plt.plot(epochs, val_loss, 'bo', label='Validation loss') | |
plt.title('Training and Validation Loss') | |
plt.xlabel('Epoch') | |
plt.ylabel('Loss Value') | |
plt.ylim([0, 1]) | |
plt.legend() | |
plt.show() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment