已开启
【众智】【清华大学深圳国际研究生院】【ID0953】【MUNIT】NPU精度达标,提交精度验收 #5
AtomGit-Bot创建于 2022年6月13日
【众智】【清华大学深圳国际研究生院】【ID0953】【MUNIT】NPU精度达标,提交精度验收 #5
已开启
从refs/pull/5/head合入到master
共 11 个文件变更+2297-0
| @@ -0,0 +1,251 @@ | |||
| 1 | + Apache License | ||
| 2 | + Version 2.0, January 2004 | ||
| 3 | + http://www.apache.org/licenses/ | ||
| 4 | + | ||
| 5 | + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION | ||
| 6 | + | ||
| 7 | + 1. Definitions. | ||
| 8 | + | ||
| 9 | + "License" shall mean the terms and conditions for use, reproduction, | ||
| 10 | + and distribution as defined by Sections 1 through 9 of this document. | ||
| 11 | + | ||
| 12 | + "Licensor" shall mean the copyright owner or entity authorized by | ||
| 13 | + the copyright owner that is granting the License. | ||
| 14 | + | ||
| 15 | + "Legal Entity" shall mean the union of the acting entity and all | ||
| 16 | + other entities that control, are controlled by, or are under common | ||
| 17 | + control with that entity. For the purposes of this definition, | ||
| 18 | + "control" means (i) the power, direct or indirect, to cause the | ||
| 19 | + direction or management of such entity, whether by contract or | ||
| 20 | + otherwise, or (ii) ownership of fifty percent (50%) or more of the | ||
| 21 | + outstanding shares, or (iii) beneficial ownership of such entity. | ||
| 22 | + | ||
| 23 | + "You" (or "Your") shall mean an individual or Legal Entity | ||
| 24 | + exercising permissions granted by this License. | ||
| 25 | + | ||
| 26 | + "Source" form shall mean the preferred form for making modifications, | ||
| 27 | + including but not limited to software source code, documentation | ||
| 28 | + source, and configuration files. | ||
| 29 | + | ||
| 30 | + "Object" form shall mean any form resulting from mechanical | ||
| 31 | + transformation or translation of a Source form, including but | ||
| 32 | + not limited to compiled object code, generated documentation, | ||
| 33 | + and conversions to other media types. | ||
| 34 | + | ||
| 35 | + "Work" shall mean the work of authorship, whether in Source or | ||
| 36 | + Object form, made available under the License, as indicated by a | ||
| 37 | + copyright notice that is included in or attached to the work | ||
| 38 | + (an example is provided in the Appendix below). | ||
| 39 | + | ||
| 40 | + "Derivative Works" shall mean any work, whether in Source or Object | ||
| 41 | + form, that is based on (or derived from) the Work and for which the | ||
| 42 | + editorial revisions, annotations, elaborations, or other modifications | ||
| 43 | + represent, as a whole, an original work of authorship. For the purposes | ||
| 44 | + of this License, Derivative Works shall not include works that remain | ||
| 45 | + separable from, or merely link (or bind by name) to the interfaces of, | ||
| 46 | + the Work and Derivative Works thereof. | ||
| 47 | + | ||
| 48 | + "Contribution" shall mean any work of authorship, including | ||
| 49 | + the original version of the Work and any modifications or additions | ||
| 50 | + to that Work or Derivative Works thereof, that is intentionally | ||
| 51 | + submitted to Licensor for inclusion in the Work by the copyright owner | ||
| 52 | + or by an individual or Legal Entity authorized to submit on behalf of | ||
| 53 | + the copyright owner. For the purposes of this definition, "submitted" | ||
| 54 | + means any form of electronic, verbal, or written communication sent | ||
| 55 | + to the Licensor or its representatives, including but not limited to | ||
| 56 | + communication on electronic mailing lists, source code control systems, | ||
| 57 | + and issue tracking systems that are managed by, or on behalf of, the | ||
| 58 | + Licensor for the purpose of discussing and improving the Work, but | ||
| 59 | + excluding communication that is conspicuously marked or otherwise | ||
| 60 | + designated in writing by the copyright owner as "Not a Contribution." | ||
| 61 | + | ||
| 62 | + "Contributor" shall mean Licensor and any individual or Legal Entity | ||
| 63 | + on behalf of whom a Contribution has been received by Licensor and | ||
| 64 | + subsequently incorporated within the Work. | ||
| 65 | + | ||
| 66 | + 2. Grant of Copyright License. Subject to the terms and conditions of | ||
| 67 | + this License, each Contributor hereby grants to You a perpetual, | ||
| 68 | + worldwide, non-exclusive, no-charge, royalty-free, irrevocable | ||
| 69 | + copyright license to reproduce, prepare Derivative Works of, | ||
| 70 | + publicly display, publicly perform, sublicense, and distribute the | ||
| 71 | + Work and such Derivative Works in Source or Object form. | ||
| 72 | + | ||
| 73 | + 3. Grant of Patent License. Subject to the terms and conditions of | ||
| 74 | + this License, each Contributor hereby grants to You a perpetual, | ||
| 75 | + worldwide, non-exclusive, no-charge, royalty-free, irrevocable | ||
| 76 | + (except as stated in this section) patent license to make, have made, | ||
| 77 | + use, offer to sell, sell, import, and otherwise transfer the Work, | ||
| 78 | + where such license applies only to those patent claims licensable | ||
| 79 | + by such Contributor that are necessarily infringed by their | ||
| 80 | + Contribution(s) alone or by combination of their Contribution(s) | ||
| 81 | + with the Work to which such Contribution(s) was submitted. If You | ||
| 82 | + institute patent litigation against any entity (including a | ||
| 83 | + cross-claim or counterclaim in a lawsuit) alleging that the Work | ||
| 84 | + or a Contribution incorporated within the Work constitutes direct | ||
| 85 | + or contributory patent infringement, then any patent licenses | ||
| 86 | + granted to You under this License for that Work shall terminate | ||
| 87 | + as of the date such litigation is filed. | ||
| 88 | + | ||
| 89 | + 4. Redistribution. You may reproduce and distribute copies of the | ||
| 90 | + Work or Derivative Works thereof in any medium, with or without | ||
| 91 | + modifications, and in Source or Object form, provided that You | ||
| 92 | + meet the following conditions: | ||
| 93 | + | ||
| 94 | + (a) You must give any other recipients of the Work or | ||
| 95 | + Derivative Works a copy of this License; and | ||
| 96 | + | ||
| 97 | + (b) You must cause any modified files to carry prominent notices | ||
| 98 | + stating that You changed the files; and | ||
| 99 | + | ||
| 100 | + (c) You must retain, in the Source form of any Derivative Works | ||
| 101 | + that You distribute, all copyright, patent, trademark, and | ||
| 102 | + attribution notices from the Source form of the Work, | ||
| 103 | + excluding those notices that do not pertain to any part of | ||
| 104 | + the Derivative Works; and | ||
| 105 | + | ||
| 106 | + (d) If the Work includes a "NOTICE" text file as part of its | ||
| 107 | + distribution, then any Derivative Works that You distribute must | ||
| 108 | + include a readable copy of the attribution notices contained | ||
| 109 | + within such NOTICE file, excluding those notices that do not | ||
| 110 | + pertain to any part of the Derivative Works, in at least one | ||
| 111 | + of the following places: within a NOTICE text file distributed | ||
| 112 | + as part of the Derivative Works; within the Source form or | ||
| 113 | + documentation, if provided along with the Derivative Works; or, | ||
| 114 | + within a display generated by the Derivative Works, if and | ||
| 115 | + wherever such third-party notices normally appear. The contents | ||
| 116 | + of the NOTICE file are for informational purposes only and | ||
| 117 | + do not modify the License. You may add Your own attribution | ||
| 118 | + notices within Derivative Works that You distribute, alongside | ||
| 119 | + or as an addendum to the NOTICE text from the Work, provided | ||
| 120 | + that such additional attribution notices cannot be construed | ||
| 121 | + as modifying the License. | ||
| 122 | + | ||
| 123 | + You may add Your own copyright statement to Your modifications and | ||
| 124 | + may provide additional or different license terms and conditions | ||
| 125 | + for use, reproduction, or distribution of Your modifications, or | ||
| 126 | + for any such Derivative Works as a whole, provided Your use, | ||
| 127 | + reproduction, and distribution of the Work otherwise complies with | ||
| 128 | + the conditions stated in this License. | ||
| 129 | + | ||
| 130 | + 5. Submission of Contributions. Unless You explicitly state otherwise, | ||
| 131 | + any Contribution intentionally submitted for inclusion in the Work | ||
| 132 | + by You to the Licensor shall be under the terms and conditions of | ||
| 133 | + this License, without any additional terms or conditions. | ||
| 134 | + Notwithstanding the above, nothing herein shall supersede or modify | ||
| 135 | + the terms of any separate license agreement you may have executed | ||
| 136 | + with Licensor regarding such Contributions. | ||
| 137 | + | ||
| 138 | + 6. Trademarks. This License does not grant permission to use the trade | ||
| 139 | + names, trademarks, service marks, or product names of the Licensor, | ||
| 140 | + except as required for reasonable and customary use in describing the | ||
| 141 | + origin of the Work and reproducing the content of the NOTICE file. | ||
| 142 | + | ||
| 143 | + 7. Disclaimer of Warranty. Unless required by applicable law or | ||
| 144 | + agreed to in writing, Licensor provides the Work (and each | ||
| 145 | + Contributor provides its Contributions) on an "AS IS" BASIS, | ||
| 146 | + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or | ||
| 147 | + implied, including, without limitation, any warranties or conditions | ||
| 148 | + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A | ||
| 149 | + PARTICULAR PURPOSE. You are solely responsible for determining the | ||
| 150 | + appropriateness of using or redistributing the Work and assume any | ||
| 151 | + risks associated with Your exercise of permissions under this License. | ||
| 152 | + | ||
| 153 | + 8. Limitation of Liability. In no event and under no legal theory, | ||
| 154 | + whether in tort (including negligence), contract, or otherwise, | ||
| 155 | + unless required by applicable law (such as deliberate and grossly | ||
| 156 | + negligent acts) or agreed to in writing, shall any Contributor be | ||
| 157 | + liable to You for damages, including any direct, indirect, special, | ||
| 158 | + incidental, or consequential damages of any character arising as a | ||
| 159 | + result of this License or out of the use or inability to use the | ||
| 160 | + Work (including but not limited to damages for loss of goodwill, | ||
| 161 | + work stoppage, computer failure or malfunction, or any and all | ||
| 162 | + other commercial damages or losses), even if such Contributor | ||
| 163 | + has been advised of the possibility of such damages. | ||
| 164 | + | ||
| 165 | + 9. Accepting Warranty or Additional Liability. While redistributing | ||
| 166 | + the Work or Derivative Works thereof, You may choose to offer, | ||
| 167 | + and charge a fee for, acceptance of support, warranty, indemnity, | ||
| 168 | + or other liability obligations and/or rights consistent with this | ||
| 169 | + License. However, in accepting such obligations, You may act only | ||
| 170 | + on Your own behalf and on Your sole responsibility, not on behalf | ||
| 171 | + of any other Contributor, and only if You agree to indemnify, | ||
| 172 | + defend, and hold each Contributor harmless for any liability | ||
| 173 | + incurred by, or claims asserted against, such Contributor by reason | ||
| 174 | + of your accepting any such warranty or additional liability. | ||
| 175 | + | ||
| 176 | + END OF TERMS AND CONDITIONS | ||
| 177 | + | ||
| 178 | + APPENDIX: How to apply the Apache License to your work. | ||
| 179 | + | ||
| 180 | + To apply the Apache License to your work, attach the following | ||
| 181 | + boilerplate notice, with the fields enclosed by brackets "[]" | ||
| 182 | + replaced with your own identifying information. (Don't include | ||
| 183 | + the brackets!) The text should be enclosed in the appropriate | ||
| 184 | + comment syntax for the file format. We also recommend that a | ||
| 185 | + file or class name and description of purpose be included on the | ||
| 186 | + same "printed page" as the copyright notice for easier | ||
| 187 | + identification within third-party archives. | ||
| 188 | + | ||
| 189 | + Copyright [yyyy] [name of copyright owner] | ||
| 190 | + | ||
| 191 | + Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 192 | + you may not use this file except in compliance with the License. | ||
| 193 | + You may obtain a copy of the License at | ||
| 194 | + | ||
| 195 | + http://www.apache.org/licenses/LICENSE-2.0 | ||
| 196 | + | ||
| 197 | + Unless required by applicable law or agreed to in writing, software | ||
| 198 | + distributed under the License is distributed on an "AS IS" BASIS, | ||
| 199 | + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 200 | + See the License for the specific language governing permissions and | ||
| 201 | + limitations under the License. | ||
| 202 | + | ||
| 203 | +## Some of TensorFlow's code is derived from Caffe, which is subject to the following copyright notice: | ||
| 204 | + | ||
| 205 | +COPYRIGHT | ||
| 206 | + | ||
| 207 | +All contributions by the University of California: | ||
| 208 | + | ||
| 209 | +Copyright (c) 2014, The Regents of the University of California (Regents) | ||
| 210 | +All rights reserved. | ||
| 211 | + | ||
| 212 | +All other contributions: | ||
| 213 | + | ||
| 214 | +Copyright (c) 2014, the respective contributors | ||
| 215 | +All rights reserved. | ||
| 216 | + | ||
| 217 | +Caffe uses a shared copyright model: each contributor holds copyright over | ||
| 218 | +their contributions to Caffe. The project versioning records all such | ||
| 219 | +contribution and copyright details. If a contributor wants to further mark | ||
| 220 | +their specific copyright on a particular contribution, they should indicate | ||
| 221 | +their copyright solely in the commit message of the change when it is | ||
| 222 | +committed. | ||
| 223 | + | ||
| 224 | +LICENSE | ||
| 225 | + | ||
| 226 | +Redistribution and use in source and binary forms, with or without | ||
| 227 | +modification, are permitted provided that the following conditions are met: | ||
| 228 | + | ||
| 229 | +1. Redistributions of source code must retain the above copyright notice, this | ||
| 230 | + list of conditions and the following disclaimer. | ||
| 231 | + | ||
| 232 | +2. Redistributions in binary form must reproduce the above copyright notice, | ||
| 233 | + this list of conditions and the following disclaimer in the documentation | ||
| 234 | + and/or other materials provided with the distribution. | ||
| 235 | + | ||
| 236 | + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | ||
| 237 | + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
| 238 | + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
| 239 | + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR | ||
| 240 | + ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
| 241 | + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
| 242 | + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
| 243 | + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
| 244 | + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
| 245 | + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| 246 | + | ||
| 247 | +CONTRIBUTION AGREEMENT | ||
| 248 | + | ||
| 249 | +By contributing to the BVLC/caffe repository through pull-request, comment, | ||
| 250 | +or otherwise, the contributor releases their content to the | ||
| 251 | +license and copyright terms herein. | ||
| @@ -0,0 +1,697 @@ | |||
| 1 | +# Copyright 2017 The TensorFlow Authors. All Rights Reserved. | ||
| 2 | +# | ||
| 3 | +# Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 4 | +# you may not use this file except in compliance with the License. | ||
| 5 | +# You may obtain a copy of the License at | ||
| 6 | +# | ||
| 7 | +# http://www.apache.org/licenses/LICENSE-2.0 | ||
| 8 | +# | ||
| 9 | +# Unless required by applicable law or agreed to in writing, software | ||
| 10 | +# distributed under the License is distributed on an "AS IS" BASIS, | ||
| 11 | +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 12 | +# See the License for the specific language governing permissions and | ||
| 13 | +# limitations under the License. | ||
| 14 | +# ============================================================================ | ||
| 15 | +# Copyright 2021 Huawei Technologies Co., Ltd | ||
| 16 | +# | ||
| 17 | +# Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 18 | +# you may not use this file except in compliance with the License. | ||
| 19 | +# You may obtain a copy of the License at | ||
| 20 | +# | ||
| 21 | +# http://www.apache.org/licenses/LICENSE-2.0 | ||
| 22 | +# | ||
| 23 | +# Unless required by applicable law or agreed to in writing, software | ||
| 24 | +# distributed under the License is distributed on an "AS IS" BASIS, | ||
| 25 | +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 26 | +# See the License for the specific language governing permissions and | ||
| 27 | +# limitations under the License. | ||
| 28 | + | ||
| 29 | +from npu_bridge.npu_init import * | ||
| 30 | +from ops import * | ||
| 31 | +from utils import * | ||
| 32 | +from glob import glob | ||
| 33 | +import time | ||
| 34 | +from tensorflow.contrib.data import batch_and_drop_remainder | ||
| 35 | + | ||
| 36 | +class MUNIT(object) : | ||
| 37 | + def __init__(self, sess, args): | ||
| 38 | + self.model_name = 'MUNIT' | ||
| 39 | + self.sess = sess | ||
| 40 | + self.checkpoint_dir = args.checkpoint_dir | ||
| 41 | + self.result_dir = args.result_dir | ||
| 42 | + self.log_dir = args.log_dir | ||
| 43 | + self.sample_dir = args.sample_dir | ||
| 44 | + #self.dataset_name = args.dataset | ||
| 45 | + self.dataset_name = args.data_path | ||
| 46 | + self.augment_flag = args.augment_flag | ||
| 47 | + | ||
| 48 | + self.epoch = args.epoch | ||
| 49 | + self.iteration = args.iteration | ||
| 50 | + | ||
| 51 | + self.gan_type = args.gan_type | ||
| 52 | + | ||
| 53 | + self.batch_size = args.batch_size | ||
| 54 | + self.print_freq = args.print_freq | ||
| 55 | + self.save_freq = args.save_freq | ||
| 56 | + self.num_style = args.num_style # for test | ||
| 57 | + self.guide_img = args.guide_img | ||
| 58 | + self.direction = args.direction | ||
| 59 | + | ||
| 60 | + self.img_h = args.img_h | ||
| 61 | + self.img_w = args.img_w | ||
| 62 | + self.img_ch = args.img_ch | ||
| 63 | + | ||
| 64 | + self.init_lr = args.lr | ||
| 65 | + self.ch = args.ch | ||
| 66 | + | ||
| 67 | + """ Weight """ | ||
| 68 | + self.gan_w = args.gan_w | ||
| 69 | + self.recon_x_w = args.recon_x_w | ||
| 70 | + self.recon_s_w = args.recon_s_w | ||
| 71 | + self.recon_c_w = args.recon_c_w | ||
| 72 | + self.recon_x_cyc_w = args.recon_x_cyc_w | ||
| 73 | + | ||
| 74 | + """ Generator """ | ||
| 75 | + self.n_res = args.n_res | ||
| 76 | + self.mlp_dim = pow(2, args.n_sample) * args.ch # default : 256 | ||
| 77 | + | ||
| 78 | + self.n_downsample = args.n_sample | ||
| 79 | + self.n_upsample = args.n_sample | ||
| 80 | + self.style_dim = args.style_dim | ||
| 81 | + | ||
| 82 | + """ Discriminator """ | ||
| 83 | + self.n_dis = args.n_dis | ||
| 84 | + self.n_scale = args.n_scale | ||
| 85 | + | ||
| 86 | + self.sample_dir = os.path.join(args.sample_dir, self.model_dir) | ||
| 87 | + check_folder(self.sample_dir) | ||
| 88 | + | ||
| 89 | + #self.trainA_dataset = glob('./dataset/{}/*.*'.format(self.dataset_name + '/trainA')) | ||
| 90 | + #self.trainB_dataset = glob('./dataset/{}/*.*'.format(self.dataset_name + '/trainB')) | ||
| 91 | + self.trainA_dataset = glob('{}/*.*'.format(self.dataset_name + '/trainA')) | ||
| 92 | + self.trainB_dataset = glob('{}/*.*'.format(self.dataset_name + '/trainB')) | ||
| 93 | + self.dataset_num = max(len(self.trainA_dataset), len(self.trainB_dataset)) | ||
| 94 | + | ||
| 95 | + # lossScale相关 | ||
| 96 | + self.bert_loss_scale = args.bert_loss_scale | ||
| 97 | + self.mmgr = {} | ||
| 98 | + | ||
| 99 | + print("##### Information #####") | ||
| 100 | + print("# gan type : ", self.gan_type) | ||
| 101 | + print("# dataset : ", self.dataset_name) | ||
| 102 | + print("# max dataset number : ", self.dataset_num) | ||
| 103 | + print("# batch_size : ", self.batch_size) | ||
| 104 | + print("# epoch : ", self.epoch) | ||
| 105 | + print("# iteration per epoch : ", self.iteration) | ||
| 106 | + print("# style in test phase : ", self.num_style) | ||
| 107 | + | ||
| 108 | + print() | ||
| 109 | + | ||
| 110 | + print("##### Generator #####") | ||
| 111 | + print("# residual blocks : ", self.n_res) | ||
| 112 | + print("# Style dimension : ", self.style_dim) | ||
| 113 | + print("# MLP dimension : ", self.mlp_dim) | ||
| 114 | + print("# Down sample : ", self.n_downsample) | ||
| 115 | + print("# Up sample : ", self.n_upsample) | ||
| 116 | + | ||
| 117 | + print() | ||
| 118 | + | ||
| 119 | + print("##### Discriminator #####") | ||
| 120 | + print("# Discriminator layer : ", self.n_dis) | ||
| 121 | + print("# Multi-scale Dis : ", self.n_scale) | ||
| 122 | + | ||
| 123 | + ################################################################################## | ||
| 124 | + # Encoder and Decoders | ||
| 125 | + ################################################################################## | ||
| 126 | + | ||
| 127 | + def Style_Encoder(self, x, reuse=False, scope='style_encoder'): | ||
| 128 | + # IN removes the original feature mean and variance that represent important style information | ||
| 129 | + channel = self.ch | ||
| 130 | + with tf.variable_scope(scope, reuse=reuse) : | ||
| 131 | + x = conv(x, channel, kernel=7, stride=1, pad=3, pad_type='reflect', scope='conv_0') | ||
| 132 | + x = relu(x) | ||
| 133 | + | ||
| 134 | + for i in range(2) : | ||
| 135 | + x = conv(x, channel*2, kernel=4, stride=2, pad=1, pad_type='reflect', scope='conv_'+str(i+1)) | ||
| 136 | + x = relu(x) | ||
| 137 | + | ||
| 138 | + channel = channel * 2 | ||
| 139 | + | ||
| 140 | + for i in range(2) : | ||
| 141 | + x = conv(x, channel, kernel=4, stride=2, pad=1, pad_type='reflect', scope='down_conv_'+str(i)) | ||
| 142 | + x = relu(x) | ||
| 143 | + | ||
| 144 | + x = adaptive_avg_pooling(x) # global average pooling | ||
| 145 | + x = conv(x, self.style_dim, kernel=1, stride=1, scope='SE_logit') | ||
| 146 | + | ||
| 147 | + return x | ||
| 148 | + | ||
| 149 | + def Content_Encoder(self, x, reuse=False, scope='content_encoder'): | ||
| 150 | + channel = self.ch | ||
| 151 | + with tf.variable_scope(scope, reuse=reuse) : | ||
| 152 | + x = conv(x, channel, kernel=7, stride=1, pad=3, pad_type='reflect', scope='conv_0') | ||
| 153 | + x = instance_norm(x, scope='ins_0') | ||
| 154 | + x = relu(x) | ||
| 155 | + | ||
| 156 | + for i in range(self.n_downsample) : | ||
| 157 | + x = conv(x, channel*2, kernel=4, stride=2, pad=1, pad_type='reflect', scope='conv_'+str(i+1)) | ||
| 158 | + x = instance_norm(x, scope='ins_'+str(i+1)) | ||
| 159 | + x = relu(x) | ||
| 160 | + | ||
| 161 | + channel = channel * 2 | ||
| 162 | + | ||
| 163 | + for i in range(self.n_res) : | ||
| 164 | + x = resblock(x, channel, scope='resblock_'+str(i)) | ||
| 165 | + | ||
| 166 | + return x | ||
| 167 | + | ||
| 168 | + def generator(self, contents, style, reuse=False, scope="decoder"): | ||
| 169 | + channel = self.mlp_dim | ||
| 170 | + with tf.variable_scope(scope, reuse=reuse) : | ||
| 171 | + mu, var = self.MLP(style) | ||
| 172 | + x = contents | ||
| 173 | + | ||
| 174 | + for i in range(self.n_res) : | ||
| 175 | + idx = 2 * i | ||
| 176 | + x = adaptive_resblock(x, channel, mu[idx], var[idx], mu[idx + 1], var[idx + 1], scope='adaptive_resblock_'+str(i)) | ||
| 177 | + | ||
| 178 | + for i in range(self.n_upsample) : | ||
| 179 | + # # IN removes the original feature mean and variance that represent important style information | ||
| 180 | + x = up_sample(x, scale_factor=2) | ||
| 181 | + x = conv(x, channel//2, kernel=5, stride=1, pad=2, pad_type='reflect', scope='conv_'+str(i)) | ||
| 182 | + x = layer_norm(x, scope='layer_norm_'+str(i)) | ||
| 183 | + x = relu(x) | ||
| 184 | + | ||
| 185 | + channel = channel // 2 | ||
| 186 | + | ||
| 187 | + x = conv(x, channels=self.img_ch, kernel=7, stride=1, pad=3, pad_type='reflect', scope='G_logit') | ||
| 188 | + x = tanh(x) | ||
| 189 | + | ||
| 190 | + return x | ||
| 191 | + | ||
| 192 | + def MLP(self, style, scope='MLP'): | ||
| 193 | + channel = self.mlp_dim | ||
| 194 | + with tf.variable_scope(scope) : | ||
| 195 | + x = style | ||
| 196 | + | ||
| 197 | + for i in range(2): | ||
| 198 | + x = fully_connected(x, channel, scope='FC_' + str(i)) | ||
| 199 | + x = relu(x) | ||
| 200 | + | ||
| 201 | + mu_list = [] | ||
| 202 | + var_list = [] | ||
| 203 | + | ||
| 204 | + for i in range(self.n_res * 2): | ||
| 205 | + mu = fully_connected(x, channel, scope='FC_mu_' + str(i)) | ||
| 206 | + var = fully_connected(x, channel, scope='FC_var_' + str(i)) | ||
| 207 | + | ||
| 208 | + mu = tf.reshape(mu, shape=[-1, 1, 1, channel]) | ||
| 209 | + var = tf.reshape(var, shape=[-1, 1, 1, channel]) | ||
| 210 | + | ||
| 211 | + mu_list.append(mu) | ||
| 212 | + var_list.append(var) | ||
| 213 | + | ||
| 214 | + return mu_list, var_list | ||
| 215 | + | ||
| 216 | + ################################################################################## | ||
| 217 | + # Discriminator | ||
| 218 | + ################################################################################## | ||
| 219 | + | ||
| 220 | + def discriminator(self, x_init, reuse=False, scope="discriminator"): | ||
| 221 | + D_logit = [] | ||
| 222 | + with tf.variable_scope(scope, reuse=reuse) : | ||
| 223 | + for scale in range(self.n_scale) : | ||
| 224 | + channel = self.ch | ||
| 225 | + x = conv(x_init, channel, kernel=4, stride=2, pad=1, pad_type='reflect', scope='ms_' + str(scale) + 'conv_0') | ||
| 226 | + x = lrelu(x, 0.2) | ||
| 227 | + | ||
| 228 | + for i in range(1, self.n_dis): | ||
| 229 | + x = conv(x, channel * 2, kernel=4, stride=2, pad=1, pad_type='reflect', scope='ms_' + str(scale) +'conv_' + str(i)) | ||
| 230 | + x = lrelu(x, 0.2) | ||
| 231 | + | ||
| 232 | + channel = channel * 2 | ||
| 233 | + | ||
| 234 | + x = conv(x, channels=1, kernel=1, stride=1, scope='ms_' + str(scale) + 'D_logit') | ||
| 235 | + D_logit.append(x) | ||
| 236 | + | ||
| 237 | + x_init = down_sample(x_init) | ||
| 238 | + | ||
| 239 | + return D_logit | ||
| 240 | + | ||
| 241 | + ################################################################################## | ||
| 242 | + # Model | ||
| 243 | + ################################################################################## | ||
| 244 | + | ||
| 245 | + def Encoder_A(self, x_A, reuse=False): | ||
| 246 | + style_A = self.Style_Encoder(x_A, reuse=reuse, scope='style_encoder_A') | ||
| 247 | + content_A = self.Content_Encoder(x_A, reuse=reuse, scope='content_encoder_A') | ||
| 248 | + | ||
| 249 | + return content_A, style_A | ||
| 250 | + | ||
| 251 | + def Encoder_B(self, x_B, reuse=False): | ||
| 252 | + style_B = self.Style_Encoder(x_B, reuse=reuse, scope='style_encoder_B') | ||
| 253 | + content_B = self.Content_Encoder(x_B, reuse=reuse, scope='content_encoder_B') | ||
| 254 | + | ||
| 255 | + return content_B, style_B | ||
| 256 | + | ||
| 257 | + def Decoder_A(self, content_B, style_A, reuse=False): | ||
| 258 | + x_ba = self.generator(contents=content_B, style=style_A, reuse=reuse, scope='decoder_A') | ||
| 259 | + | ||
| 260 | + return x_ba | ||
| 261 | + | ||
| 262 | + def Decoder_B(self, content_A, style_B, reuse=False): | ||
| 263 | + x_ab = self.generator(contents=content_A, style=style_B, reuse=reuse, scope='decoder_B') | ||
| 264 | + | ||
| 265 | + return x_ab | ||
| 266 | + | ||
| 267 | + def discriminate_real(self, x_A, x_B): | ||
| 268 | + real_A_logit = self.discriminator(x_A, scope="discriminator_A") | ||
| 269 | + real_B_logit = self.discriminator(x_B, scope="discriminator_B") | ||
| 270 | + | ||
| 271 | + return real_A_logit, real_B_logit | ||
| 272 | + | ||
| 273 | + def discriminate_fake(self, x_ba, x_ab): | ||
| 274 | + fake_A_logit = self.discriminator(x_ba, reuse=True, scope="discriminator_A") | ||
| 275 | + fake_B_logit = self.discriminator(x_ab, reuse=True, scope="discriminator_B") | ||
| 276 | + | ||
| 277 | + return fake_A_logit, fake_B_logit | ||
| 278 | + | ||
| 279 | + def build_model(self): | ||
| 280 | + self.lr = tf.placeholder(tf.float32, name='learning_rate') | ||
| 281 | + | ||
| 282 | + """ Input Image""" | ||
| 283 | + Image_Data_Class = ImageData(self.img_h, self.img_w, self.img_ch, self.augment_flag) | ||
| 284 | + | ||
| 285 | + trainA = tf.data.Dataset.from_tensor_slices(self.trainA_dataset) | ||
| 286 | + trainB = tf.data.Dataset.from_tensor_slices(self.trainB_dataset) | ||
| 287 | + | ||
| 288 | + trainA = trainA.prefetch(self.batch_size).shuffle(self.dataset_num).map(Image_Data_Class.image_processing, num_parallel_calls=8).apply(batch_and_drop_remainder(self.batch_size)).repeat() | ||
| 289 | + trainB = trainB.prefetch(self.batch_size).shuffle(self.dataset_num).map(Image_Data_Class.image_processing, num_parallel_calls=8).apply(batch_and_drop_remainder(self.batch_size)).repeat() | ||
| 290 | + | ||
| 291 | + trainA_iterator = trainA.make_one_shot_iterator() | ||
| 292 | + trainB_iterator = trainB.make_one_shot_iterator() | ||
| 293 | + | ||
| 294 | + | ||
| 295 | + self.domain_A = trainA_iterator.get_next() | ||
| 296 | + self.domain_B = trainB_iterator.get_next() | ||
| 297 | + | ||
| 298 | + | ||
| 299 | + """ Define Encoder, Generator, Discriminator """ | ||
| 300 | + self.style_a = tf.placeholder(tf.float32, shape=[self.batch_size, 1, 1, self.style_dim], name='style_a') | ||
| 301 | + self.style_b = tf.placeholder(tf.float32, shape=[self.batch_size, 1, 1, self.style_dim], name='style_b') | ||
| 302 | + | ||
| 303 | + # encode | ||
| 304 | + content_a, style_a_prime = self.Encoder_A(self.domain_A) | ||
| 305 | + content_b, style_b_prime = self.Encoder_B(self.domain_B) | ||
| 306 | + | ||
| 307 | + # decode (within domain) | ||
| 308 | + x_aa = self.Decoder_A(content_B=content_a, style_A=style_a_prime) | ||
| 309 | + x_bb = self.Decoder_B(content_A=content_b, style_B=style_b_prime) | ||
| 310 | + | ||
| 311 | + # decode (cross domain) | ||
| 312 | + x_ba = self.Decoder_A(content_B=content_b, style_A=self.style_a, reuse=True) | ||
| 313 | + x_ab = self.Decoder_B(content_A=content_a, style_B=self.style_b, reuse=True) | ||
| 314 | + | ||
| 315 | + # encode again | ||
| 316 | + content_b_, style_a_ = self.Encoder_A(x_ba, reuse=True) | ||
| 317 | + content_a_, style_b_ = self.Encoder_B(x_ab, reuse=True) | ||
| 318 | + | ||
| 319 | + # decode again (if needed) | ||
| 320 | + if self.recon_x_cyc_w > 0 : | ||
| 321 | + x_aba = self.Decoder_A(content_B=content_a_, style_A=style_a_prime, reuse=True) | ||
| 322 | + x_bab = self.Decoder_B(content_A=content_b_, style_B=style_b_prime, reuse=True) | ||
| 323 | + | ||
| 324 | + cyc_recon_A = L1_loss(x_aba, self.domain_A) | ||
| 325 | + cyc_recon_B = L1_loss(x_bab, self.domain_B) | ||
| 326 | + | ||
| 327 | + else : | ||
| 328 | + cyc_recon_A = 0.0 | ||
| 329 | + cyc_recon_B = 0.0 | ||
| 330 | + | ||
| 331 | + real_A_logit, real_B_logit = self.discriminate_real(self.domain_A, self.domain_B) | ||
| 332 | + fake_A_logit, fake_B_logit = self.discriminate_fake(x_ba, x_ab) | ||
| 333 | + | ||
| 334 | + """ Define Loss """ | ||
| 335 | + G_ad_loss_a = generator_loss(self.gan_type, fake_A_logit) | ||
| 336 | + G_ad_loss_b = generator_loss(self.gan_type, fake_B_logit) | ||
| 337 | + | ||
| 338 | + D_ad_loss_a = discriminator_loss(self.gan_type, real_A_logit, fake_A_logit) | ||
| 339 | + D_ad_loss_b = discriminator_loss(self.gan_type, real_B_logit, fake_B_logit) | ||
| 340 | + | ||
| 341 | + recon_A = L1_loss(x_aa, self.domain_A) # reconstruction | ||
| 342 | + recon_B = L1_loss(x_bb, self.domain_B) # reconstruction | ||
| 343 | + | ||
| 344 | + # The style reconstruction loss encourages | ||
| 345 | + # diverse outputs given different style codes | ||
| 346 | + recon_style_A = L1_loss(style_a_, self.style_a) | ||
| 347 | + recon_style_B = L1_loss(style_b_, self.style_b) | ||
| 348 | + | ||
| 349 | + # The content reconstruction loss encourages | ||
| 350 | + # the translated image to preserve semantic content of the input image | ||
| 351 | + recon_content_A = L1_loss(content_a_, content_a) | ||
| 352 | + recon_content_B = L1_loss(content_b_, content_b) | ||
| 353 | + | ||
| 354 | + | ||
| 355 | + Generator_A_loss = self.gan_w * G_ad_loss_a + \ | ||
| 356 | + self.recon_x_w * recon_A + \ | ||
| 357 | + self.recon_s_w * recon_style_A + \ | ||
| 358 | + self.recon_c_w * recon_content_A + \ | ||
| 359 | + self.recon_x_cyc_w * cyc_recon_A | ||
| 360 | + | ||
| 361 | + Generator_B_loss = self.gan_w * G_ad_loss_b + \ | ||
| 362 | + self.recon_x_w * recon_B + \ | ||
| 363 | + self.recon_s_w * recon_style_B + \ | ||
| 364 | + self.recon_c_w * recon_content_B + \ | ||
| 365 | + self.recon_x_cyc_w * cyc_recon_B | ||
| 366 | + | ||
| 367 | + Discriminator_A_loss = self.gan_w * D_ad_loss_a | ||
| 368 | + Discriminator_B_loss = self.gan_w * D_ad_loss_b | ||
| 369 | + | ||
| 370 | + self.Generator_loss = Generator_A_loss + Generator_B_loss + regularization_loss('encoder') + regularization_loss('decoder') | ||
| 371 | + self.Discriminator_loss = Discriminator_A_loss + Discriminator_B_loss + regularization_loss('discriminator') | ||
| 372 | + | ||
| 373 | + """ Training """ | ||
| 374 | + t_vars = tf.trainable_variables() | ||
| 375 | + G_vars = [var for var in t_vars if 'decoder' in var.name or 'encoder' in var.name] | ||
| 376 | + D_vars = [var for var in t_vars if 'discriminator' in var.name] | ||
| 377 | + | ||
| 378 | + | ||
| 379 | + # self.G_optim = tf.train.AdamOptimizer(self.lr, beta1=0.5, beta2=0.999).minimize(self.Generator_loss, var_list=G_vars) | ||
H | |||
| 380 | + # self.D_optim = tf.train.AdamOptimizer(self.lr, beta1=0.5, beta2=0.999).minimize(self.Discriminator_loss, var_list=D_vars) | ||
| 381 | + | ||
| 382 | + # 开启loss_scale | ||
| 383 | + self.G_optim = tf.train.AdamOptimizer(self.lr, beta1=0.5, beta2=0.999) | ||
| 384 | + self.D_optim = tf.train.AdamOptimizer(self.lr, beta1=0.5, beta2=0.999) | ||
| 385 | + # 开启loss_scale | ||
| 386 | + self.G_optim = self.open_loss_scale(self.G_optim, 'G') | ||
| 387 | + self.D_optim = self.open_loss_scale(self.D_optim, 'D') | ||
| 388 | + | ||
| 389 | + self.G_optim = self.G_optim.minimize(self.Generator_loss, var_list=G_vars) | ||
| 390 | + self.D_optim = self.D_optim.minimize(self.Discriminator_loss, var_list=D_vars) | ||
| 391 | + | ||
| 392 | + | ||
| 393 | + | ||
| 394 | + """" Summary """ | ||
| 395 | + self.all_G_loss = tf.summary.scalar("Generator_loss", self.Generator_loss) | ||
| 396 | + self.all_D_loss = tf.summary.scalar("Discriminator_loss", self.Discriminator_loss) | ||
| 397 | + self.G_A_loss = tf.summary.scalar("G_A_loss", Generator_A_loss) | ||
| 398 | + self.G_B_loss = tf.summary.scalar("G_B_loss", Generator_B_loss) | ||
| 399 | + self.D_A_loss = tf.summary.scalar("D_A_loss", Discriminator_A_loss) | ||
| 400 | + self.D_B_loss = tf.summary.scalar("D_B_loss", Discriminator_B_loss) | ||
| 401 | + | ||
| 402 | + self.G_loss = tf.summary.merge([self.G_A_loss, self.G_B_loss, self.all_G_loss]) | ||
| 403 | + self.D_loss = tf.summary.merge([self.D_A_loss, self.D_B_loss, self.all_D_loss]) | ||
| 404 | + | ||
| 405 | + """ Image """ | ||
| 406 | + self.fake_A = x_ba | ||
| 407 | + self.fake_B = x_ab | ||
| 408 | + | ||
| 409 | + self.real_A = self.domain_A | ||
| 410 | + self.real_B = self.domain_B | ||
| 411 | + | ||
| 412 | + """ Test """ | ||
| 413 | + self.test_image = tf.placeholder(tf.float32, [1, self.img_h, self.img_w, self.img_ch], name='test_image') | ||
| 414 | + self.test_style = tf.placeholder(tf.float32, [1, 1, 1, self.style_dim], name='test_style') | ||
| 415 | + | ||
| 416 | + test_content_a, _ = self.Encoder_A(self.test_image, reuse=True) | ||
| 417 | + test_content_b, _ = self.Encoder_B(self.test_image, reuse=True) | ||
| 418 | + | ||
| 419 | + self.test_fake_A = self.Decoder_A(content_B=test_content_b, style_A=self.test_style, reuse=True) | ||
| 420 | + self.test_fake_B = self.Decoder_B(content_A=test_content_a, style_B=self.test_style, reuse=True) | ||
| 421 | + | ||
| 422 | + """ Guided Image Translation """ | ||
| 423 | + self.content_image = tf.placeholder(tf.float32, [1, self.img_h, self.img_w, self.img_ch], name='content_image') | ||
| 424 | + self.style_image = tf.placeholder(tf.float32, [1, self.img_h, self.img_w, self.img_ch], name='guide_style_image') | ||
| 425 | + | ||
| 426 | + if self.direction == 'a2b' : | ||
| 427 | + guide_content_A, guide_style_A = self.Encoder_A(self.content_image, reuse=True) | ||
| 428 | + guide_content_B, guide_style_B = self.Encoder_B(self.style_image, reuse=True) | ||
| 429 | + | ||
| 430 | + else : | ||
| 431 | + guide_content_B, guide_style_B = self.Encoder_B(self.content_image, reuse=True) | ||
| 432 | + guide_content_A, guide_style_A = self.Encoder_A(self.style_image, reuse=True) | ||
| 433 | + | ||
| 434 | + self.guide_fake_A = self.Decoder_A(content_B=guide_content_B, style_A=guide_style_A, reuse=True) | ||
| 435 | + self.guide_fake_B = self.Decoder_B(content_A=guide_content_A, style_B=guide_style_B, reuse=True) | ||
| 436 | + | ||
| 437 | + def train(self): | ||
| 438 | + # initialize all variables | ||
| 439 | + tf.global_variables_initializer().run() | ||
| 440 | + | ||
| 441 | + # saver to save model | ||
| 442 | + self.saver = tf.train.Saver() | ||
| 443 | + | ||
| 444 | + # summary writer | ||
| 445 | + self.writer = tf.summary.FileWriter(self.log_dir + '/' + self.model_dir, self.sess.graph) | ||
| 446 | + | ||
| 447 | + # restore check-point if it exits | ||
| 448 | + could_load, checkpoint_counter = self.load(self.checkpoint_dir) | ||
| 449 | + if could_load: | ||
| 450 | + start_epoch = (int)(checkpoint_counter / self.iteration) | ||
| 451 | + start_batch_id = checkpoint_counter - start_epoch * self.iteration | ||
| 452 | + counter = checkpoint_counter | ||
| 453 | + print(" [*] Load SUCCESS") | ||
| 454 | + else: | ||
| 455 | + start_epoch = 0 | ||
| 456 | + start_batch_id = 0 | ||
| 457 | + counter = 1 | ||
| 458 | + print(" [!] Load failed...") | ||
| 459 | + | ||
| 460 | + # loop for epoch | ||
| 461 | + start_time = time.time() | ||
| 462 | + for epoch in range(start_epoch, self.epoch): | ||
| 463 | + | ||
| 464 | + lr = self.init_lr * pow(0.5, epoch) | ||
| 465 | + | ||
| 466 | + for idx in range(start_batch_id, self.iteration): | ||
| 467 | + style_a = np.random.normal(loc=0.0, scale=1.0, size=[self.batch_size, 1, 1, self.style_dim]) | ||
| 468 | + style_b = np.random.normal(loc=0.0, scale=1.0, size=[self.batch_size, 1, 1, self.style_dim]) | ||
| 469 | + | ||
| 470 | + train_feed_dict = { | ||
| 471 | + self.style_a : style_a, | ||
| 472 | + self.style_b : style_b, | ||
| 473 | + self.lr : lr | ||
| 474 | + } | ||
| 475 | + | ||
| 476 | + # Update D | ||
| 477 | + # _, d_loss, summary_str = \ | ||
| 478 | + # self.sess.run([self.D_optim, self.Discriminator_loss, self.D_loss], feed_dict = train_feed_dict) | ||
| 479 | + | ||
| 480 | + # 保存scale value,并打印到日志里,来观察整网的溢出情况 | ||
| 481 | + _, d_loss, summary_str, d_scale = \ | ||
| 482 | + self.sess.run([self.D_optim, self.Discriminator_loss, self.D_loss, self.mmgr['D'].get_loss_scale()], | ||
| 483 | + feed_dict=train_feed_dict) | ||
| 484 | + | ||
| 485 | + self.writer.add_summary(summary_str, counter) | ||
| 486 | + | ||
| 487 | + # Update G | ||
| 488 | + #batch_A_images, batch_B_images, fake_A, fake_B, _, g_loss, summary_str = self.sess.run([self.real_A, self.real_B, self.fake_A, self.fake_B, self.G_optim, self.Generator_loss, self.G_loss], feed_dict = train_feed_dict) | ||
| 489 | + batch_A_images, batch_B_images, fake_A, fake_B, _, g_loss, summary_str, g_scale = self.sess.run( | ||
| 490 | + [self.real_A, self.real_B, self.fake_A, self.fake_B, self.G_optim, self.Generator_loss, | ||
| 491 | + self.G_loss, self.mmgr['G'].get_loss_scale()], feed_dict=train_feed_dict) | ||
| 492 | + self.writer.add_summary(summary_str, counter) | ||
| 493 | + | ||
| 494 | + # display training status | ||
| 495 | + counter += 1 | ||
| 496 | + print("Epoch: [%2d] [%6d/%6d] time: %4.4f d_loss: %.8f, g_loss: %.8f, d_scale: %d, g_scale: %d\n" \ | ||
| 497 | + % (epoch, idx, self.iteration, time.time() - start_time, d_loss, g_loss, d_scale, g_scale)) | ||
| 498 | + # print("Epoch: [%2d] [%6d/%6d] time: %4.4f d_loss: %.8f, g_loss: %.8f\n" \ | ||
| 499 | + # % (epoch, idx, self.iteration, time.time() - start_time, d_loss, g_loss)) | ||
| 500 | + | ||
| 501 | + if np.mod(idx+1, self.print_freq) == 0 : | ||
| 502 | + save_images(batch_A_images, [self.batch_size, 1], | ||
| 503 | + '{}/real_A_{:02d}_{:06d}.jpg'.format(self.sample_dir, epoch, idx+1)) | ||
| 504 | + # save_images(batch_B_images, [self.batch_size, 1], | ||
| 505 | + # './{}/real_B_{}_{:02d}_{:06d}.jpg'.format(self.sample_dir, gpu_id, epoch, idx+1)) | ||
| 506 | + | ||
| 507 | + # save_images(fake_A, [self.batch_size, 1], | ||
| 508 | + # './{}/fake_A_{}_{:02d}_{:06d}.jpg'.format(self.sample_dir, gpu_id, epoch, idx+1)) | ||
| 509 | + save_images(fake_B, [self.batch_size, 1], | ||
| 510 | + '{}/fake_B_{:02d}_{:06d}.jpg'.format(self.sample_dir, epoch, idx+1)) | ||
| 511 | + | ||
| 512 | + if np.mod(idx+1, self.save_freq) == 0 : | ||
| 513 | + self.save(self.checkpoint_dir, counter) | ||
| 514 | + | ||
| 515 | + # After an epoch, start_batch_id is set to zero | ||
| 516 | + # non-zero value is only for the first epoch after loading pre-trained model | ||
| 517 | + start_batch_id = 0 | ||
| 518 | + | ||
| 519 | + # save model for final step | ||
| 520 | + self.save(self.checkpoint_dir, counter) | ||
| 521 | + | ||
| 522 | + | ||
| 523 | + | ||
| 524 | + def model_dir(self): | ||
| 525 | + return "{}_{}".format(self.model_name, self.gan_type) | ||
| 526 | + #return "{}_{}_{}".format(self.model_name, self.dataset_name, self.gan_type) | ||
| 527 | + | ||
| 528 | + def save(self, checkpoint_dir, step): | ||
| 529 | + checkpoint_dir = os.path.join(checkpoint_dir, self.model_dir) | ||
| 530 | + | ||
| 531 | + if not os.path.exists(checkpoint_dir): | ||
| 532 | + os.makedirs(checkpoint_dir) | ||
| 533 | + | ||
| 534 | + self.saver.save(self.sess, os.path.join(checkpoint_dir, self.model_name + '.model'), global_step=step) | ||
| 535 | + | ||
| 536 | + def load(self, checkpoint_dir): | ||
| 537 | + import re | ||
| 538 | + print(" [*] Reading checkpoints...") | ||
| 539 | + checkpoint_dir = os.path.join(checkpoint_dir, self.model_dir) | ||
| 540 | + | ||
| 541 | + ckpt = tf.train.get_checkpoint_state(checkpoint_dir) | ||
| 542 | + if ckpt and ckpt.model_checkpoint_path: | ||
| 543 | + ckpt_name = os.path.basename(ckpt.model_checkpoint_path) | ||
| 544 | + self.saver.restore(self.sess, os.path.join(checkpoint_dir, ckpt_name)) | ||
| 545 | + counter = int(next(re.finditer("(\d+)(?!.*\d)", ckpt_name)).group(0)) | ||
| 546 | + print(" [*] Success to read {}".format(ckpt_name)) | ||
| 547 | + return True, counter | ||
| 548 | + else: | ||
| 549 | + print(" [*] Failed to find a checkpoint") | ||
| 550 | + return False, 0 | ||
| 551 | + | ||
| 552 | + def test(self): | ||
| 553 | + tf.global_variables_initializer().run() | ||
| 554 | + | ||
| 555 | + #test_A_files = glob('{}/*.*'.format(self.dataset_name + '/testA')) | ||
| 556 | + #test_B_files = glob('{}/*.*'.format(self.dataset_name + '/testB')) | ||
| 557 | + test_A_files = self.trainA_dataset | ||
| 558 | + test_B_files = self.trainB_dataset | ||
| 559 | + | ||
| 560 | + self.saver = tf.train.Saver() | ||
| 561 | + could_load, checkpoint_counter = self.load(self.checkpoint_dir) | ||
| 562 | + self.result_dir = os.path.join(self.result_dir, self.model_dir) | ||
| 563 | + check_folder(self.result_dir) | ||
| 564 | + | ||
| 565 | + if could_load : | ||
| 566 | + print(" [*] Load SUCCESS") | ||
| 567 | + else : | ||
| 568 | + print(" [!] Load failed...") | ||
| 569 | + | ||
| 570 | + # write html for visual comparison | ||
| 571 | + index_path = os.path.join(self.result_dir, 'index.html') | ||
| 572 | + index = open(index_path, 'w') | ||
| 573 | + index.write("<html><body><table><tr>") | ||
| 574 | + index.write("<th>name</th><th>input</th><th>output</th></tr>") | ||
| 575 | + | ||
| 576 | + cnt = 0 | ||
| 577 | + for sample_file in test_A_files : # A -> B | ||
| 578 | + print('Processing A image: ' + sample_file) | ||
| 579 | + sample_image = np.asarray(load_test_data(sample_file, size_h=self.img_h, size_w=self.img_w)) | ||
| 580 | + file_name = os.path.basename(sample_file).split(".")[0] | ||
| 581 | + file_extension = os.path.basename(sample_file).split(".")[1] | ||
| 582 | + | ||
| 583 | + for i in range(self.num_style) : | ||
| 584 | + test_style = np.random.normal(loc=0.0, scale=1.0, size=[1, 1, 1, self.style_dim]) | ||
| 585 | + image_path = os.path.join(self.result_dir, '{}_style{}.{}'.format(file_name, i, file_extension)) | ||
| 586 | + | ||
| 587 | + fake_img = self.sess.run(self.test_fake_B, feed_dict = {self.test_image : sample_image, self.test_style : test_style}) | ||
| 588 | + save_images(fake_img, [1, 1], image_path) | ||
| 589 | + | ||
| 590 | + index.write("<td>%s</td>" % os.path.basename(image_path)) | ||
| 591 | + index.write("<td><img src='%s' width='%d' height='%d'></td>" % (sample_file if os.path.isabs(sample_file) else ( | ||
| 592 | + '../..' + os.path.sep + sample_file), self.img_w, self.img_h)) | ||
| 593 | + index.write("<td><img src='%s' width='%d' height='%d'></td>" % (image_path if os.path.isabs(image_path) else ( | ||
| 594 | + '../..' + os.path.sep + image_path), self.img_w, self.img_h)) | ||
| 595 | + index.write("</tr>") | ||
| 596 | + cnt += 1 | ||
| 597 | + if cnt == 1: break | ||
| 598 | + | ||
| 599 | + cnt = 0 | ||
| 600 | + for sample_file in test_B_files : # B -> A | ||
| 601 | + print('Processing B image: ' + sample_file) | ||
| 602 | + sample_image = np.asarray(load_test_data(sample_file, size_h=self.img_h, size_w=self.img_w)) | ||
| 603 | + file_name = os.path.basename(sample_file).split(".")[0] | ||
| 604 | + file_extension = os.path.basename(sample_file).split(".")[1] | ||
| 605 | + | ||
| 606 | + for i in range(self.num_style): | ||
| 607 | + test_style = np.random.normal(loc=0.0, scale=1.0, size=[1, 1, 1, self.style_dim]) | ||
| 608 | + image_path = os.path.join(self.result_dir, '{}_style{}.{}'.format(file_name, i, file_extension)) | ||
| 609 | + | ||
| 610 | + fake_img = self.sess.run(self.test_fake_A, feed_dict={self.test_image: sample_image, self.test_style: test_style}) | ||
| 611 | + save_images(fake_img, [1, 1], image_path) | ||
| 612 | + | ||
| 613 | + index.write("<td>%s</td>" % os.path.basename(image_path)) | ||
| 614 | + index.write("<td><img src='%s' width='%d' height='%d'></td>" % (sample_file if os.path.isabs(sample_file) else ( | ||
| 615 | + '../..' + os.path.sep + sample_file), self.img_w, self.img_h)) | ||
| 616 | + index.write("<td><img src='%s' width='%d' height='%d'></td>" % (image_path if os.path.isabs(image_path) else ( | ||
| 617 | + '../..' + os.path.sep + image_path), self.img_w, self.img_h)) | ||
| 618 | + index.write("</tr>") | ||
| 619 | + cnt += 1 | ||
| 620 | + if cnt == 1: break | ||
| 621 | + index.close() | ||
| 622 | + | ||
| 623 | + def style_guide_test(self): | ||
| 624 | + tf.global_variables_initializer().run() | ||
| 625 | + test_A_files = glob('./dataset/{}/*.*'.format(self.dataset_name + '/testA')) | ||
| 626 | + test_B_files = glob('./dataset/{}/*.*'.format(self.dataset_name + '/testB')) | ||
| 627 | + | ||
| 628 | + style_file = np.asarray(load_test_data(self.guide_img, size_h=self.img_h, size_w=self.img_w)) | ||
| 629 | + | ||
| 630 | + self.saver = tf.train.Saver() | ||
| 631 | + could_load, checkpoint_counter = self.load(self.checkpoint_dir) | ||
| 632 | + self.result_dir = os.path.join(self.result_dir, self.model_dir, 'guide') | ||
| 633 | + check_folder(self.result_dir) | ||
| 634 | + | ||
| 635 | + if could_load: | ||
| 636 | + print(" [*] Load SUCCESS") | ||
| 637 | + else: | ||
| 638 | + print(" [!] Load failed...") | ||
| 639 | + | ||
| 640 | + # write html for visual comparison | ||
| 641 | + index_path = os.path.join(self.result_dir, 'index.html') | ||
| 642 | + index = open(index_path, 'w') | ||
| 643 | + index.write("<html><body><table><tr>") | ||
| 644 | + index.write("<th>name</th><th>input</th><th>output</th></tr>") | ||
| 645 | + | ||
| 646 | + if self.direction == 'a2b' : | ||
| 647 | + for sample_file in test_A_files: # A -> B | ||
| 648 | + print('Processing A image: ' + sample_file) | ||
| 649 | + sample_image = np.asarray(load_test_data(sample_file, size_h=self.img_h, size_w=self.img_w)) | ||
| 650 | + image_path = os.path.join(self.result_dir, '{}'.format(os.path.basename(sample_file))) | ||
| 651 | + | ||
| 652 | + fake_img = self.sess.run(self.guide_fake_B, feed_dict={self.content_image: sample_image, self.style_image : style_file}) | ||
| 653 | + save_images(fake_img, [1, 1], image_path) | ||
| 654 | + | ||
| 655 | + index.write("<td>%s</td>" % os.path.basename(image_path)) | ||
| 656 | + index.write("<td><img src='%s' width='%d' height='%d'></td>" % (sample_file if os.path.isabs(sample_file) else ( | ||
| 657 | + '../../..' + os.path.sep + sample_file), self.img_w, self.img_h)) | ||
| 658 | + index.write("<td><img src='%s' width='%d' height='%d'></td>" % (image_path if os.path.isabs(image_path) else ( | ||
| 659 | + '../../..' + os.path.sep + image_path), self.img_w, self.img_h)) | ||
| 660 | + index.write("</tr>") | ||
| 661 | + | ||
| 662 | + else : | ||
| 663 | + for sample_file in test_B_files: # B -> A | ||
| 664 | + print('Processing B image: ' + sample_file) | ||
| 665 | + sample_image = np.asarray(load_test_data(sample_file, size_h=self.img_h, size_w=self.img_w)) | ||
| 666 | + image_path = os.path.join(self.result_dir, '{}'.format(os.path.basename(sample_file))) | ||
| 667 | + | ||
| 668 | + fake_img = self.sess.run(self.guide_fake_A, feed_dict={self.content_image: sample_image, self.style_image : style_file}) | ||
| 669 | + save_images(fake_img, [1, 1], image_path) | ||
| 670 | + | ||
| 671 | + index.write("<td>%s</td>" % os.path.basename(image_path)) | ||
| 672 | + index.write("<td><img src='%s' width='%d' height='%d'></td>" % (sample_file if os.path.isabs(sample_file) else ( | ||
| 673 | + '../../..' + os.path.sep + sample_file), self.img_w, self.img_h)) | ||
| 674 | + index.write("<td><img src='%s' width='%d' height='%d'></td>" % (image_path if os.path.isabs(image_path) else ( | ||
| 675 | + '../../..' + os.path.sep + image_path), self.img_w, self.img_h)) | ||
| 676 | + index.write("</tr>") | ||
| 677 | + index.close() | ||
| 678 | + | ||
| 679 | + def open_loss_scale(self, opt, key): | ||
| 680 | + opt_tmp = opt | ||
| 681 | + if self.bert_loss_scale == 0: | ||
| 682 | + # loss_scale_manager = ExponentialUpdateLossScaleManager(init_loss_scale=2 ** 32, incr_every_n_steps=1000, | ||
| 683 | + # decr_every_n_nan_or_inf=2, decr_ratio=0.5) | ||
| 684 | + loss_scale_manager = ExponentialUpdateLossScaleManager(init_loss_scale = 2 ** 10, incr_every_n_steps = 100, decr_every_n_nan_or_inf = 2, decr_ratio = 0.8) | ||
| 685 | + print("lossScale type: exponential") | ||
| 686 | + elif self.bert_loss_scale >= 1: | ||
| 687 | + loss_scale_manager = FixedLossScaleManager(loss_scale=self.bert_loss_scale) | ||
| 688 | + else: | ||
| 689 | + raise ValueError("Invalid loss scale: %d" % self.bert_loss_scale) | ||
| 690 | + self.mmgr[key] = loss_scale_manager | ||
| 691 | + # device数是否大于1,如果大于1,进行分布式训练 | ||
| 692 | + # if ops_adapter.size() > 1: | ||
| 693 | + # opt_tmp = NPUDistributedOptimizer(opt_tmp) | ||
| 694 | + # opt = NPULossScaleOptimizer(opt_tmp, loss_scale_manager, is_distributed=True) | ||
| 695 | + # else: | ||
| 696 | + opt = NPULossScaleOptimizer(opt_tmp, loss_scale_manager) | ||
| 697 | + return opt | ||
| @@ -0,0 +1,188 @@ | |||
| 1 | +- [基本信息](#基本信息.md) | ||
| 2 | +- [概述](#概述.md) | ||
| 3 | +- [训练环境准备](#训练环境准备.md) | ||
| 4 | +- [快速上手](#快速上手.md) | ||
| 5 | +- [训练结果](#训练结果.md) | ||
| 6 | +- [高级参考](#高级参考.md) | ||
| 7 | +<h2 id="基本信息.md">基本信息</h2> | ||
| 8 | + | ||
| 9 | +**发布者(Publisher):Huawei** | ||
| 10 | + | ||
| 11 | +**应用领域(Application Domain):Computer Vision** | ||
| 12 | + | ||
| 13 | +**版本(Version):1.2** | ||
| 14 | + | ||
| 15 | +**修改时间(Modified) :2022.06.12** | ||
| 16 | + | ||
| 17 | +**大小(Size):104KB** | ||
| 18 | + | ||
| 19 | +**框架(Framework):TensorFlow 1.15.0** | ||
| 20 | + | ||
| 21 | +**模型格式(Model Format):ckpt** | ||
| 22 | + | ||
| 23 | +**精度(Precision):Mixed** | ||
| 24 | + | ||
| 25 | +**处理器(Processor):昇腾910** | ||
| 26 | + | ||
| 27 | +**应用级别(Categories):Official** | ||
| 28 | + | ||
| 29 | +**描述(Description):基于TensorFlow框架的图像迁移算法** | ||
| 30 | + | ||
| 31 | +<h2 id="概述.md">概述</h2> | ||
| 32 | +Munit是2018年提出的多模态无监督图像转换框架,可以从给定的源域图像生成不同风格的目标域图像输出。 | ||
| 33 | + | ||
| 34 | + | ||
| 35 | +- 参考论文: | ||
| 36 | + | ||
| 37 | + https://arxiv.org/abs/1804.04732 | ||
| 38 | + | ||
| 39 | +- 参考实现: | ||
| 40 | + | ||
| 41 | + https://github.com/taki0112/MUNIT-Tensorflow | ||
| 42 | + | ||
| 43 | +- 适配昇腾 AI 处理器的实现: | ||
| 44 | + | ||
| 45 | + https://gitee.com/harry-zzh/modelzoo/edit/master/contrib/Tensorflow/MUNIT_ID0953_for_TensorFlow/ | ||
| 46 | + | ||
| 47 | + | ||
| 48 | + | ||
| 49 | +- 通过Git获取对应commit\_id的代码方法如下: | ||
| 50 | + | ||
| 51 | + ``` | ||
| 52 | + git clone {repository_url} # 克隆仓库的代码 | ||
| 53 | + cd {repository_name} # 切换到模型的代码仓目录 | ||
| 54 | + git checkout {branch} # 切换到对应分支 | ||
| 55 | + git reset --hard {commit_id} # 代码设置到对应的commit_id | ||
| 56 | + cd {code_path} # 切换到模型代码所在路径,若仓库下只有该模型,则无需切换 | ||
| 57 | + ``` | ||
| 58 | + | ||
| 59 | +## 默认配置<a name="section91661242121611"></a> | ||
| 60 | + | ||
| 61 | +- 训练超参 | ||
| 62 | + | ||
| 63 | + - Batch size: 1 | ||
| 64 | + - Train epoch: 1 | ||
| 65 | + - Train step: 100000 | ||
| 66 | + | ||
| 67 | + | ||
| 68 | +## 支持特性<a name="section1899153513554"></a> | ||
| 69 | + | ||
| 70 | +| 特性列表 | 是否支持 | | ||
| 71 | +|-------|------| | ||
| 72 | +| 分布式训练 | 否 | | ||
| 73 | +| 混合精度 | 否 | | ||
| 74 | +| 并行数据 | 否 | | ||
| 75 | + | ||
| 76 | + | ||
| 77 | +<h2 id="训练环境准备.md">训练环境准备</h2> | ||
| 78 | + | ||
| 79 | +1. 硬件环境准备请参见各硬件产品文档"[驱动和固件安装升级指南]( https://support.huawei.com/enterprise/zh/category/ai-computing-platform-pid-1557196528909)"。需要在硬件设备上安装与CANN版本配套的固件与驱动。 | ||
| 80 | +2. 宿主机上需要安装Docker并登录[Ascend Hub中心](https://ascendhub.huawei.com/#/detail?name=ascend-tensorflow-arm)获取镜像。 | ||
| 81 | + | ||
| 82 | + 当前模型支持的镜像列表如[表1](#zh-cn_topic_0000001074498056_table1519011227314)所示。 | ||
| 83 | + | ||
| 84 | + **表 1** 镜像列表 | ||
| 85 | + | ||
| 86 | + <a name="zh-cn_topic_0000001074498056_table1519011227314"></a> | ||
| 87 | + <table><thead align="left"><tr id="zh-cn_topic_0000001074498056_row0190152218319"><th class="cellrowborder" valign="top" width="47.32%" id="mcps1.2.4.1.1"><p id="zh-cn_topic_0000001074498056_p1419132211315"><a name="zh-cn_topic_0000001074498056_p1419132211315"></a><a name="zh-cn_topic_0000001074498056_p1419132211315"></a><em id="i1522884921219"><a name="i1522884921219"></a><a name="i1522884921219"></a>镜像名称</em></p> | ||
| 88 | + </th> | ||
| 89 | + <th class="cellrowborder" valign="top" width="25.52%" id="mcps1.2.4.1.2"><p id="zh-cn_topic_0000001074498056_p75071327115313"><a name="zh-cn_topic_0000001074498056_p75071327115313"></a><a name="zh-cn_topic_0000001074498056_p75071327115313"></a><em id="i1522994919122"><a name="i1522994919122"></a><a name="i1522994919122"></a>镜像版本</em></p> | ||
| 90 | + </th> | ||
| 91 | + <th class="cellrowborder" valign="top" width="27.16%" id="mcps1.2.4.1.3"><p id="zh-cn_topic_0000001074498056_p1024411406234"><a name="zh-cn_topic_0000001074498056_p1024411406234"></a><a name="zh-cn_topic_0000001074498056_p1024411406234"></a><em id="i723012493123"><a name="i723012493123"></a><a name="i723012493123"></a>配套CANN版本</em></p> | ||
| 92 | + </th> | ||
| 93 | + </tr> | ||
| 94 | + </thead> | ||
| 95 | + <tbody><tr id="zh-cn_topic_0000001074498056_row71915221134"><td class="cellrowborder" valign="top" width="47.32%" headers="mcps1.2.4.1.1 "><a name="zh-cn_topic_0000001074498056_ul81691515131910"></a><a name="zh-cn_topic_0000001074498056_ul81691515131910"></a><ul id="zh-cn_topic_0000001074498056_ul81691515131910"><li><em id="i82326495129"><a name="i82326495129"></a><a name="i82326495129"></a>ARM架构:<a href="https://ascend.huawei.com/ascendhub/#/detail?name=ascend-tensorflow-arm" target="_blank" rel="noopener noreferrer">ascend-tensorflow-arm</a></em></li><li><em id="i18233184918125"><a name="i18233184918125"></a><a name="i18233184918125"></a>x86架构:<a href="https://ascend.huawei.com/ascendhub/#/detail?name=ascend-tensorflow-x86" target="_blank" rel="noopener noreferrer">ascend-tensorflow-x86</a></em></li></ul> | ||
| 96 | + </td> | ||
| 97 | + <td class="cellrowborder" valign="top" width="25.52%" headers="mcps1.2.4.1.2 "><p id="zh-cn_topic_0000001074498056_p1450714271532"><a name="zh-cn_topic_0000001074498056_p1450714271532"></a><a name="zh-cn_topic_0000001074498056_p1450714271532"></a><em id="i72359495125"><a name="i72359495125"></a><a name="i72359495125"></a>20.2.0</em></p> | ||
| 98 | + </td> | ||
| 99 | + <td class="cellrowborder" valign="top" width="27.16%" headers="mcps1.2.4.1.3 "><p id="zh-cn_topic_0000001074498056_p18244640152312"><a name="zh-cn_topic_0000001074498056_p18244640152312"></a><a name="zh-cn_topic_0000001074498056_p18244640152312"></a><em id="i162363492129"><a name="i162363492129"></a><a name="i162363492129"></a><a href="https://support.huawei.com/enterprise/zh/ascend-computing/cann-pid-251168373/software" target="_blank" rel="noopener noreferrer">20.2</a></em></p> | ||
| 100 | + </td> | ||
| 101 | + </tr> | ||
| 102 | + </tbody> | ||
| 103 | + </table> | ||
| 104 | + | ||
| 105 | + | ||
| 106 | +<h2 id="快速上手.md">快速上手</h2> | ||
| 107 | + | ||
| 108 | +- 数据集准备 | ||
| 109 | +1. 模型训练使用edges2shoes数据集,数据集请用户自行获取。 | ||
| 110 | + | ||
| 111 | +## 模型训练<a name="section715881518135"></a> | ||
| 112 | + | ||
| 113 | +- 单击“立即下载”,并选择合适的下载方式下载源码包。 | ||
| 114 | + | ||
| 115 | +- 启动训练之前,首先要配置程序运行相关环境变量。 | ||
| 116 | + | ||
| 117 | + 环境变量配置信息参见: | ||
| 118 | + | ||
| 119 | + [Ascend 910训练平台环境变量设置](https://gitee.com/ascend/modelzoo/wikis/Ascend%20910%E8%AE%AD%E7%BB%83%E5%B9%B3%E5%8F%B0%E7%8E%AF%E5%A2%83%E5%8F%98%E9%87%8F%E8%AE%BE%E7%BD%AE?sort_id=3148819) | ||
| 120 | + | ||
| 121 | +- 单卡训练 | ||
| 122 | + | ||
| 123 | + 1. 配置训练参数。 | ||
| 124 | + | ||
| 125 | + 首先在脚本test/train_full_1p.sh中,配置batch_size、steps、epochs、data_path等参数,请用户根据实际路径配置data_path,或者在启动训练的命令行中以参数形式下发。 | ||
| 126 | + | ||
| 127 | + ``` | ||
| 128 | + batch_size=1 | ||
| 129 | + train_steps=100000 | ||
| 130 | + epochs=1 | ||
| 131 | + data_path="./dataset/edges2shoes/train" | ||
| 132 | + ``` | ||
| 133 | + | ||
| 134 | + 2. 启动训练。 | ||
| 135 | + | ||
| 136 | + 启动单卡训练 (脚本为MUNIT_ID0953_for_TensorFlow/test/train_full_1p.sh) | ||
| 137 | + | ||
| 138 | + ``` | ||
| 139 | + bash train_full_1p.sh | ||
| 140 | + ``` | ||
| 141 | + | ||
| 142 | +<h2 id="训练结果.md">训练结果</h2> | ||
| 143 | + | ||
| 144 | +- 精度结果比对 | ||
| 145 | + | ||
| 146 | +取训练最后1000个steps的loss,计算平均值,进行结果比对。 | ||
| 147 | + | ||
| 148 | +|精度指标项|GPU实测|NPU实测| | ||
| 149 | +|---|---|---| | ||
| 150 | +|d_loss|2.619421507950002|2.7996314894200007| | ||
| 151 | +|g_loss|4.192780654629998|4.389258856830003| | ||
| 152 | + | ||
| 153 | + | ||
| 154 | +<h2 id="高级参考.md">高级参考</h2> | ||
| 155 | + | ||
| 156 | +## 脚本和示例代码<a name="section08421615141513"></a> | ||
| 157 | + | ||
| 158 | +``` | ||
| 159 | +├── MUNIT.py //网络训练与测试代码 | ||
| 160 | +├── main.py //主函数设置代码 | ||
| 161 | +├── ops.py //基础模块代码 | ||
| 162 | +├── utils.py //工具函数代码 | ||
| 163 | +├── README.md //代码说明文档 | ||
| 164 | +├── test | ||
| 165 | +│ ├──train_performance_1p.sh //单卡训练验证性能启动脚本 | ||
| 166 | +│ ├──train_full_1p.sh //单卡全量训练启动脚本 | ||
| 167 | + | ||
| 168 | +``` | ||
| 169 | + | ||
| 170 | +## 脚本参数<a name="section6669162441511"></a> | ||
| 171 | + | ||
| 172 | +``` | ||
| 173 | +--data_path 数据集路径,默认:./dataset/edges2shoes/train | ||
| 174 | +--phase 运行模式,默认:train | ||
| 175 | +--batch_size 每个NPU的batch size,默认:1 | ||
| 176 | +--learing_rate 初始学习率,默认:0.001 | ||
| 177 | +--iteration 每个epcoh训练步数,默认:100000 | ||
| 178 | +--epoch 训练epcoh数量,默认:1 | ||
| 179 | +--result 结果输出路径,默认:./test/output/${ASCEND_DEVICE_ID} | ||
| 180 | +``` | ||
| 181 | + | ||
| 182 | +## 训练过程<a name="section1589455252218"></a> | ||
| 183 | + | ||
| 184 | +1. 通过“模型训练”中的训练指令启动单卡卡训练。 | ||
| 185 | + | ||
| 186 | +2. 参考脚本的模型存储路径为./test/output/${ASCEND_DEVICE_ID}/checkpoint/MUNIT_lsgan。 | ||
| 187 | + | ||
| 188 | + | ||
| @@ -0,0 +1,212 @@ | |||
| 1 | +# Copyright 2017 The TensorFlow Authors. All Rights Reserved. | ||
| 2 | +# | ||
| 3 | +# Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 4 | +# you may not use this file except in compliance with the License. | ||
| 5 | +# You may obtain a copy of the License at | ||
| 6 | +# | ||
| 7 | +# http://www.apache.org/licenses/LICENSE-2.0 | ||
| 8 | +# | ||
| 9 | +# Unless required by applicable law or agreed to in writing, software | ||
| 10 | +# distributed under the License is distributed on an "AS IS" BASIS, | ||
| 11 | +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 12 | +# See the License for the specific language governing permissions and | ||
| 13 | +# limitations under the License. | ||
| 14 | +# ============================================================================ | ||
| 15 | +# Copyright 2021 Huawei Technologies Co., Ltd | ||
| 16 | +# | ||
| 17 | +# Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 18 | +# you may not use this file except in compliance with the License. | ||
| 19 | +# You may obtain a copy of the License at | ||
| 20 | +# | ||
| 21 | +# http://www.apache.org/licenses/LICENSE-2.0 | ||
| 22 | +# | ||
| 23 | +# Unless required by applicable law or agreed to in writing, software | ||
| 24 | +# distributed under the License is distributed on an "AS IS" BASIS, | ||
| 25 | +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 26 | +# See the License for the specific language governing permissions and | ||
| 27 | +# limitations under the License. | ||
| 28 | + | ||
| 29 | +from npu_bridge.npu_init import * | ||
| 30 | +import tensorflow as tf | ||
| 31 | +from MUNIT import MUNIT | ||
| 32 | +import argparse | ||
| 33 | +from utils import * | ||
| 34 | +# from help_modelarts import modelarts_result2obs | ||
| 35 | +import precision_tool.tf_config as npu_tf_config | ||
| 36 | + | ||
| 37 | +"""parsing and configuration""" | ||
| 38 | +def parse_args(): | ||
| 39 | + desc = "Tensorflow implementation of MUNIT" | ||
| 40 | + parser = argparse.ArgumentParser(description=desc) | ||
| 41 | + parser.add_argument('--code_dir', type=str, default='code', help='code_dir') | ||
| 42 | + parser.add_argument('--phase', type=str, default='train', help='train or test or guide') | ||
| 43 | + parser.add_argument('--dataset', type=str, default='summer2winter', help='dataset_name') | ||
| 44 | + parser.add_argument('--data_path', type=str, default='summer2winter', help='dataset_name') | ||
| 45 | + parser.add_argument('--augment_flag', type=bool, default=False, help='Image augmentation use or not') | ||
| 46 | + parser.add_argument('--obs_dir', type=str, default='./output/', help='obs_dir') | ||
| 47 | + | ||
| 48 | + parser.add_argument('--epoch', type=int, default=10, help='The number of epochs to run') | ||
| 49 | + parser.add_argument('--iteration', type=int, default=100000, help='The number of training iterations') | ||
| 50 | + parser.add_argument('--batch_size', type=int, default=1, help='The batch size') | ||
| 51 | + parser.add_argument('--print_freq', type=int, default=1000, help='The number of image_print_freq') | ||
| 52 | + parser.add_argument('--save_freq', type=int, default=1000, help='The number of ckpt_save_freq') | ||
| 53 | + parser.add_argument('--num_style', type=int, default=3, help='number of styles to sample') | ||
| 54 | + parser.add_argument('--direction', type=str, default='a2b', help='direction of style guided image translation') | ||
| 55 | + parser.add_argument('--guide_img', type=str, default='guide.jpg', help='Style guided image translation') | ||
| 56 | + | ||
| 57 | + parser.add_argument('--gan_type', type=str, default='lsgan', help='GAN loss type [gan / lsgan]') | ||
| 58 | + | ||
| 59 | + parser.add_argument('--lr', type=float, default=0.0001, help='The learning rate') | ||
| 60 | + parser.add_argument('--gan_w', type=float, default=1.0, help='weight of adversarial loss') | ||
| 61 | + parser.add_argument('--recon_x_w', type=float, default=10.0, help='weight of image reconstruction loss') | ||
| 62 | + parser.add_argument('--recon_s_w', type=float, default=1.0, help='weight of style reconstruction loss') | ||
| 63 | + parser.add_argument('--recon_c_w', type=float, default=1.0, help='weight of content reconstruction loss') | ||
| 64 | + parser.add_argument('--recon_x_cyc_w', type=float, default=0.0, help='weight of explicit style augmented cycle consistency loss') | ||
| 65 | + | ||
| 66 | + parser.add_argument('--ch', type=int, default=64, help='base channel number per layer') | ||
| 67 | + parser.add_argument('--style_dim', type=int, default=8, help='length of style code') | ||
| 68 | + parser.add_argument('--n_sample', type=int, default=2, help='number of sampling layers in content encoder') | ||
| 69 | + parser.add_argument('--n_res', type=int, default=4, help='number of residual blocks in content encoder/decoder') | ||
| 70 | + | ||
| 71 | + parser.add_argument('--n_dis', type=int, default=4, help='number of discriminator layer') | ||
| 72 | + parser.add_argument('--n_scale', type=int, default=3, help='number of scales') | ||
| 73 | + | ||
| 74 | + parser.add_argument('--img_h', type=int, default=256, help='The size of image hegiht') | ||
| 75 | + parser.add_argument('--img_w', type=int, default=256, help='The size of image width') | ||
| 76 | + parser.add_argument('--img_ch', type=int, default=3, help='The size of image channel') | ||
| 77 | + | ||
| 78 | + parser.add_argument('--result', type=str, default='results', | ||
| 79 | + help='Directory name to save the results') | ||
| 80 | + parser.add_argument('--checkpoint_dir', type=str, default='checkpoint', | ||
| 81 | + help='Directory name to save the checkpoints') | ||
| 82 | + parser.add_argument('--result_dir', type=str, default='results', | ||
| 83 | + help='Directory name to save the generated images') | ||
| 84 | + parser.add_argument('--log_dir', type=str, default='logs', | ||
| 85 | + help='Directory name to save training logs') | ||
| 86 | + parser.add_argument('--sample_dir', type=str, default='samples', | ||
| 87 | + help='Directory name to save the samples on training') | ||
| 88 | + | ||
| 89 | + # parser.add_argument('--use_fp16', type=bool, default=True) | ||
| 90 | + parser.add_argument('--bert_loss_scale', type=int, default=0) | ||
| 91 | + | ||
| 92 | + | ||
| 93 | + return check_args(parser.parse_args()) | ||
| 94 | + | ||
| 95 | +"""checking arguments""" | ||
| 96 | +def check_args(args): | ||
| 97 | + # --checkpoint_dir | ||
| 98 | + args.checkpoint_dir = os.path.join(args.result, args.checkpoint_dir) | ||
| 99 | + check_folder(args.checkpoint_dir) | ||
| 100 | + | ||
| 101 | + # --result_dir | ||
| 102 | + args.result_dir = os.path.join(args.result, args.result_dir) | ||
| 103 | + check_folder(args.result_dir) | ||
| 104 | + | ||
| 105 | + # --result_dir | ||
| 106 | + args.log_dir = os.path.join(args.result, args.log_dir) | ||
| 107 | + check_folder(args.log_dir) | ||
| 108 | + | ||
| 109 | + # --dump_dir | ||
| 110 | + args.dump_dir = os.path.join(args.result, "dump") | ||
| 111 | + check_folder(args.dump_dir) | ||
| 112 | + | ||
| 113 | + # --sample_dir | ||
| 114 | + args.sample_dir = os.path.join(args.result, args.sample_dir) | ||
| 115 | + check_folder(args.sample_dir) | ||
| 116 | + | ||
| 117 | + # --epoch | ||
| 118 | + try: | ||
| 119 | + assert args.epoch >= 1 | ||
| 120 | + except: | ||
| 121 | + print('number of epochs must be larger than or equal to one') | ||
| 122 | + | ||
| 123 | + # --batch_size | ||
| 124 | + try: | ||
| 125 | + assert args.batch_size >= 1 | ||
| 126 | + except: | ||
| 127 | + print('batch size must be larger than or equal to one') | ||
| 128 | + return args | ||
| 129 | + | ||
| 130 | +"""main""" | ||
| 131 | +def main(): | ||
| 132 | + # parse arguments | ||
| 133 | + args = parse_args() | ||
| 134 | + if args is None: | ||
| 135 | + exit() | ||
| 136 | + | ||
| 137 | + ############################## npu modify ######################### | ||
| 138 | + config = tf.ConfigProto(allow_soft_placement=True) | ||
| 139 | + custom_op = config.graph_options.rewrite_options.custom_optimizers.add() | ||
| 140 | + custom_op.name = "NpuOptimizer" | ||
| 141 | + custom_op.parameter_map["use_off_line"].b = True | ||
| 142 | + # # 混合精度 | ||
| 143 | + custom_op.parameter_map["precision_mode"].s = tf.compat.as_bytes("allow_fp32_to_fp16") | ||
| 144 | + #custom_op.parameter_map["precision_mode"].s = tf.compat.as_bytes("force_fp32") | ||
| 145 | + # 算子黑名单 | ||
| 146 | + #custom_op.parameter_map["modify_mixlist"].s = tf.compat.as_bytes("./ops_info.json") | ||
| 147 | + # custom_op.parameter_map["modify_mixlist"].s = tf.compat.as_bytes(os.path.join(args.code_dir, "ops_info.json")) | ||
| 148 | + # print(os.path.isfile(os.path.join(args.code_dir, "ops_info.json"))) | ||
| 149 | + # print(os.path.join(args.code_dir, "ops_info.json")) | ||
| 150 | + | ||
| 151 | + # 判断是否溢出 | ||
| 152 | + # # dump_path:dump数据存放路径,该参数指定的目录需要在启动训练的环境上(容器或Host侧)提前创建且确保安装时配置的运行用户具有读写权限 | ||
| 153 | + # custom_op.parameter_map["dump_path"].s = tf.compat.as_bytes(args.dump_dir) | ||
| 154 | + # # enable_dump_debug:是否开启溢出检测功能 | ||
| 155 | + # custom_op.parameter_map["enable_dump_debug"].b = True | ||
| 156 | + # # dump_debug_mode:溢出检测模式,取值:all/aicore_overflow/atomic_overflow | ||
| 157 | + # custom_op.parameter_map["dump_debug_mode"].s = tf.compat.as_bytes("all") | ||
| 158 | + # custom_op = npu_tf_config.update_custom_op(custom_op, action='overflow') | ||
| 159 | + | ||
| 160 | + # # 关闭全部融合规则 | ||
| 161 | + # config = npu_tf_config.session_dump_config(config, action='fusion_off') | ||
| 162 | + | ||
| 163 | + config.graph_options.rewrite_options.remapping = RewriterConfig.OFF #off remap | ||
| 164 | + config = npu_config_proto(config_proto=config) | ||
| 165 | + | ||
| 166 | + | ||
| 167 | + | ||
| 168 | + # if args.use_fp16 and (args.bert_loss_scale not in [None, -1]): | ||
| 169 | + # opt_tmp = custom_op | ||
| 170 | + # if args.bert_loss_scale == 0: | ||
| 171 | + # loss_scale_manager = ExponentialUpdateLossScaleManager(init_loss_scale=2 ** 32, incr_every_n_steps=1000, | ||
| 172 | + # decr_every_n_nan_or_inf=2, decr_ratio=0.5) | ||
| 173 | + # elif args.bert_loss_scale >= 1: | ||
| 174 | + # loss_scale_manager = FixedLossScaleManager(loss_scale=args.bert_loss_scale) | ||
| 175 | + # else: | ||
| 176 | + # raise ValueError("Invalid loss scale: %d" % args.bert_loss_scale) | ||
| 177 | + # # device数是否大于1,如果大于1,进行分布式训练 | ||
| 178 | + # # if ops_adapter.size() > 1: | ||
| 179 | + # # opt_tmp = NPUDistributedOptimizer(opt_tmp) | ||
| 180 | + # # custom_op = NPULossScaleOptimizer(opt_tmp, loss_scale_manager, is_distributed=True) | ||
| 181 | + # # else: | ||
| 182 | + # custom_op = NPULossScaleOptimizer(opt_tmp, loss_scale_manager) | ||
| 183 | + | ||
| 184 | + # open session | ||
| 185 | + with tf.Session(config=config) as sess: | ||
| 186 | + gan = MUNIT(sess, args) | ||
| 187 | + ############################## npu modify ######################### | ||
| 188 | + | ||
| 189 | + # build graph | ||
| 190 | + gan.build_model() | ||
| 191 | + | ||
| 192 | + # show network architecture | ||
| 193 | + show_all_variables() | ||
| 194 | + | ||
| 195 | + if args.phase == 'train' : | ||
| 196 | + # launch the graph in a session | ||
| 197 | + gan.train() | ||
| 198 | + print(" [*] Training finished!") | ||
| 199 | + | ||
| 200 | + if args.phase == 'test' : | ||
| 201 | + gan.test() | ||
| 202 | + print(" [*] Test finished!") | ||
| 203 | + | ||
| 204 | + if args.phase == 'guide' : | ||
| 205 | + gan.style_guide_test() | ||
| 206 | + print(" [*] Guide finished!") | ||
| 207 | + | ||
| 208 | + #modelarts_result2obs(args) | ||
| 209 | + | ||
| 210 | +if __name__ == '__main__': | ||
| 211 | + main() | ||
| 212 | + | ||
| @@ -0,0 +1,63 @@ | |||
| 1 | +# Copyright 2017 The TensorFlow Authors. All Rights Reserved. | ||
| 2 | +# | ||
| 3 | +# Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 4 | +# you may not use this file except in compliance with the License. | ||
| 5 | +# You may obtain a copy of the License at | ||
| 6 | +# | ||
| 7 | +# http://www.apache.org/licenses/LICENSE-2.0 | ||
| 8 | +# | ||
| 9 | +# Unless required by applicable law or agreed to in writing, software | ||
| 10 | +# distributed under the License is distributed on an "AS IS" BASIS, | ||
| 11 | +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 12 | +# See the License for the specific language governing permissions and | ||
| 13 | +# limitations under the License. | ||
| 14 | +# ============================================================================ | ||
| 15 | +# Copyright 2021 Huawei Technologies Co., Ltd | ||
| 16 | +# | ||
| 17 | +# Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 18 | +# you may not use this file except in compliance with the License. | ||
| 19 | +# You may obtain a copy of the License at | ||
| 20 | +# | ||
| 21 | +# http://www.apache.org/licenses/LICENSE-2.0 | ||
| 22 | +# | ||
| 23 | +# Unless required by applicable law or agreed to in writing, software | ||
| 24 | +# distributed under the License is distributed on an "AS IS" BASIS, | ||
| 25 | +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 26 | +# See the License for the specific language governing permissions and | ||
| 27 | +# limitations under the License. | ||
| 28 | + | ||
| 29 | +import os | ||
| 30 | +import argparse | ||
| 31 | +import sys | ||
| 32 | + | ||
| 33 | +# 解析输入参数data_url | ||
| 34 | +parser = argparse.ArgumentParser() | ||
| 35 | +parser.add_argument("--data_url", type=str, default="/home/ma-user/modelarts/inputs/data_url_0") | ||
| 36 | +parser.add_argument("--train_url", type=str, default="/home/ma-user/modelarts/outputs/train_url_0/") | ||
| 37 | +config = parser.parse_args() | ||
| 38 | + | ||
| 39 | +print("[CANN-Modelzoo] code_dir path is [%s]" % (sys.path[0])) | ||
| 40 | +code_dir = sys.path[0] | ||
| 41 | +os.chdir(code_dir) | ||
| 42 | +print("[CANN-Modelzoo] work_dir path is [%s]" % (os.getcwd())) | ||
| 43 | + | ||
| 44 | +print("[CANN-Modelzoo] before train - list my run files:") | ||
| 45 | +os.system("ls -al /usr/local/Ascend/ascend-toolkit/") | ||
| 46 | + | ||
| 47 | +print("[CANN-Modelzoo] before train - list my dataset files:") | ||
| 48 | +os.system("ls -al %s" % config.data_url) | ||
| 49 | + | ||
| 50 | +print("[CANN-Modelzoo] start run train shell") | ||
| 51 | +# 设置sh文件格式为linux可执行 | ||
| 52 | +os.system("dos2unix ./test/*") | ||
| 53 | + | ||
| 54 | +# 执行train_full_1p.sh或者train_performance_1p.sh,需要用户自己指定 | ||
| 55 | +# full和performance的差异,performance只需要执行很少的step,控制在15分钟以内,主要关注性能FPS | ||
| 56 | +os.system("bash ./test/train_full_1p.sh --data_path=%s --output_path=%s " % (config.data_url, config.train_url)) | ||
| 57 | + | ||
| 58 | +print("[CANN-Modelzoo] finish run train shell") | ||
| 59 | + | ||
| 60 | +# 将当前执行目录所有文件拷贝到obs的output进行备份 | ||
| 61 | +print("[CANN-Modelzoo] after train - list my output files:") | ||
| 62 | +os.system("cp -r %s %s " % (code_dir, config.train_url)) | ||
| 63 | +os.system("ls -al %s" % config.train_url) | ||
| @@ -0,0 +1,63 @@ | |||
| 1 | +# Copyright 2017 The TensorFlow Authors. All Rights Reserved. | ||
| 2 | +# | ||
| 3 | +# Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 4 | +# you may not use this file except in compliance with the License. | ||
| 5 | +# You may obtain a copy of the License at | ||
| 6 | +# | ||
| 7 | +# http://www.apache.org/licenses/LICENSE-2.0 | ||
| 8 | +# | ||
| 9 | +# Unless required by applicable law or agreed to in writing, software | ||
| 10 | +# distributed under the License is distributed on an "AS IS" BASIS, | ||
| 11 | +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 12 | +# See the License for the specific language governing permissions and | ||
| 13 | +# limitations under the License. | ||
| 14 | +# ============================================================================ | ||
| 15 | +# Copyright 2021 Huawei Technologies Co., Ltd | ||
| 16 | +# | ||
| 17 | +# Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 18 | +# you may not use this file except in compliance with the License. | ||
| 19 | +# You may obtain a copy of the License at | ||
| 20 | +# | ||
| 21 | +# http://www.apache.org/licenses/LICENSE-2.0 | ||
| 22 | +# | ||
| 23 | +# Unless required by applicable law or agreed to in writing, software | ||
| 24 | +# distributed under the License is distributed on an "AS IS" BASIS, | ||
| 25 | +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 26 | +# See the License for the specific language governing permissions and | ||
| 27 | +# limitations under the License. | ||
| 28 | + | ||
| 29 | +import os | ||
| 30 | +import argparse | ||
| 31 | +import sys | ||
| 32 | + | ||
| 33 | +# 解析输入参数data_url | ||
| 34 | +parser = argparse.ArgumentParser() | ||
| 35 | +parser.add_argument("--data_url", type=str, default="/home/ma-user/modelarts/inputs/data_url_0") | ||
| 36 | +parser.add_argument("--train_url", type=str, default="/home/ma-user/modelarts/outputs/train_url_0/") | ||
| 37 | +config = parser.parse_args() | ||
| 38 | + | ||
| 39 | +print("[CANN-Modelzoo] code_dir path is [%s]" % (sys.path[0])) | ||
| 40 | +code_dir = sys.path[0] | ||
| 41 | +os.chdir(code_dir) | ||
| 42 | +print("[CANN-Modelzoo] work_dir path is [%s]" % (os.getcwd())) | ||
| 43 | + | ||
| 44 | +print("[CANN-Modelzoo] before train - list my run files:") | ||
| 45 | +os.system("ls -al /usr/local/Ascend/ascend-toolkit/") | ||
| 46 | + | ||
| 47 | +print("[CANN-Modelzoo] before train - list my dataset files:") | ||
| 48 | +os.system("ls -al %s" % config.data_url) | ||
| 49 | + | ||
| 50 | +print("[CANN-Modelzoo] start run train shell") | ||
| 51 | +# 设置sh文件格式为linux可执行 | ||
| 52 | +os.system("dos2unix ./test/*") | ||
| 53 | + | ||
| 54 | +# 执行train_full_1p.sh或者train_performance_1p.sh,需要用户自己指定 | ||
| 55 | +# full和performance的差异,performance只需要执行很少的step,控制在15分钟以内,主要关注性能FPS | ||
| 56 | +os.system("bash ./test/train_performance_1p.sh --data_path=%s --output_path=%s " % (config.data_url, config.train_url)) | ||
| 57 | + | ||
| 58 | +print("[CANN-Modelzoo] finish run train shell") | ||
| 59 | + | ||
| 60 | +# 将当前执行目录所有文件拷贝到obs的output进行备份 | ||
| 61 | +print("[CANN-Modelzoo] after train - list my output files:") | ||
| 62 | +os.system("cp -r %s %s " % (code_dir, config.train_url)) | ||
| 63 | +os.system("ls -al %s" % config.train_url) | ||
| @@ -0,0 +1,3 @@ | |||
| 1 | +FuncStatus:OK | ||
| 2 | +PerfStatus:NOK | ||
| 3 | +PrecisionStatus:OK | ||
| @@ -0,0 +1,243 @@ | |||
| 1 | +# Copyright 2017 The TensorFlow Authors. All Rights Reserved. | ||
| 2 | +# | ||
| 3 | +# Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 4 | +# you may not use this file except in compliance with the License. | ||
| 5 | +# You may obtain a copy of the License at | ||
| 6 | +# | ||
| 7 | +# http://www.apache.org/licenses/LICENSE-2.0 | ||
| 8 | +# | ||
| 9 | +# Unless required by applicable law or agreed to in writing, software | ||
| 10 | +# distributed under the License is distributed on an "AS IS" BASIS, | ||
| 11 | +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 12 | +# See the License for the specific language governing permissions and | ||
| 13 | +# limitations under the License. | ||
| 14 | +# ============================================================================ | ||
| 15 | +# Copyright 2021 Huawei Technologies Co., Ltd | ||
| 16 | +# | ||
| 17 | +# Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 18 | +# you may not use this file except in compliance with the License. | ||
| 19 | +# You may obtain a copy of the License at | ||
| 20 | +# | ||
| 21 | +# http://www.apache.org/licenses/LICENSE-2.0 | ||
| 22 | +# | ||
| 23 | +# Unless required by applicable law or agreed to in writing, software | ||
| 24 | +# distributed under the License is distributed on an "AS IS" BASIS, | ||
| 25 | +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 26 | +# See the License for the specific language governing permissions and | ||
| 27 | +# limitations under the License. | ||
| 28 | + | ||
| 29 | +from npu_bridge.npu_init import * | ||
| 30 | +import tensorflow as tf | ||
| 31 | +import tensorflow.contrib as tf_contrib | ||
| 32 | +from utils import pytorch_kaiming_weight_factor | ||
| 33 | + | ||
| 34 | +factor, mode, uniform = pytorch_kaiming_weight_factor(a=0.0, uniform=False) | ||
| 35 | +weight_init = tf_contrib.layers.variance_scaling_initializer(factor=factor, mode=mode, uniform=uniform) | ||
| 36 | +weight_regularizer = tf_contrib.layers.l2_regularizer(scale=0.0001) | ||
| 37 | + | ||
| 38 | +################################################################################## | ||
| 39 | +# Layer | ||
| 40 | +################################################################################## | ||
| 41 | + | ||
| 42 | +def conv(x, channels, kernel=4, stride=2, pad=0, pad_type='zero', use_bias=True, scope='conv'): | ||
| 43 | + with tf.variable_scope(scope): | ||
| 44 | + if scope.__contains__("discriminator") : | ||
| 45 | + weight_init = tf.random_normal_initializer(mean=0.0, stddev=0.02) | ||
| 46 | + else : | ||
| 47 | + weight_init = tf_contrib.layers.variance_scaling_initializer() | ||
| 48 | + | ||
| 49 | + if pad > 0: | ||
| 50 | + h = x.get_shape().as_list()[1] | ||
| 51 | + if h % stride == 0: | ||
| 52 | + pad = pad * 2 | ||
| 53 | + else: | ||
| 54 | + pad = max(kernel - (h % stride), 0) | ||
| 55 | + | ||
| 56 | + pad_top = pad // 2 | ||
| 57 | + pad_bottom = pad - pad_top | ||
| 58 | + pad_left = pad // 2 | ||
| 59 | + pad_right = pad - pad_left | ||
| 60 | + | ||
| 61 | + if pad_type == 'zero': | ||
| 62 | + x = tf.pad(x, [[0, 0], [pad_top, pad_bottom], [pad_left, pad_right], [0, 0]]) | ||
| 63 | + if pad_type == 'reflect': | ||
| 64 | + x = tf.pad(x, [[0, 0], [pad_top, pad_bottom], [pad_left, pad_right], [0, 0]], mode='REFLECT') | ||
| 65 | + | ||
| 66 | + x = tf.layers.conv2d(inputs=x, filters=channels, | ||
| 67 | + kernel_size=kernel, kernel_initializer=weight_init, | ||
| 68 | + kernel_regularizer=weight_regularizer, | ||
| 69 | + strides=stride, use_bias=use_bias) | ||
| 70 | + | ||
| 71 | + return x | ||
| 72 | + | ||
| 73 | +def fully_connected(x, units, use_bias=True, scope='fully_connected'): | ||
| 74 | + with tf.variable_scope(scope): | ||
| 75 | + x = flatten(x) | ||
| 76 | + x = tf.layers.dense(x, units=units, kernel_initializer=weight_init, | ||
| 77 | + kernel_regularizer=weight_regularizer, | ||
| 78 | + use_bias=use_bias) | ||
| 79 | + | ||
| 80 | + return x | ||
| 81 | + | ||
| 82 | +def flatten(x) : | ||
| 83 | + return tf.layers.flatten(x) | ||
| 84 | + | ||
| 85 | +################################################################################## | ||
| 86 | +# Residual-block | ||
| 87 | +################################################################################## | ||
| 88 | + | ||
| 89 | +def resblock(x_init, channels, use_bias=True, scope='resblock'): | ||
| 90 | + with tf.variable_scope(scope): | ||
| 91 | + with tf.variable_scope('res1'): | ||
| 92 | + x = conv(x_init, channels, kernel=3, stride=1, pad=1, pad_type='reflect', use_bias=use_bias) | ||
| 93 | + x = instance_norm(x) | ||
| 94 | + x = relu(x) | ||
| 95 | + | ||
| 96 | + with tf.variable_scope('res2'): | ||
| 97 | + x = conv(x, channels, kernel=3, stride=1, pad=1, pad_type='reflect', use_bias=use_bias) | ||
| 98 | + x = instance_norm(x) | ||
| 99 | + | ||
| 100 | + return x + x_init | ||
| 101 | + | ||
| 102 | +def adaptive_resblock(x_init, channels, gamma1, beta1, gamma2, beta2, use_bias=True, scope='adaptive_resblock') : | ||
| 103 | + with tf.variable_scope(scope): | ||
| 104 | + with tf.variable_scope('res1'): | ||
| 105 | + x = conv(x_init, channels, kernel=3, stride=1, pad=1, pad_type='reflect', use_bias=use_bias) | ||
| 106 | + x = adaptive_instance_norm(x, gamma1, beta1) | ||
| 107 | + x = relu(x) | ||
| 108 | + | ||
| 109 | + with tf.variable_scope('res2'): | ||
| 110 | + x = conv(x, channels, kernel=3, stride=1, pad=1, pad_type='reflect', use_bias=use_bias) | ||
| 111 | + x = adaptive_instance_norm(x, gamma2, beta2) | ||
| 112 | + | ||
| 113 | + return x + x_init | ||
| 114 | + | ||
| 115 | +################################################################################## | ||
| 116 | +# Sampling | ||
| 117 | +################################################################################## | ||
| 118 | + | ||
| 119 | +def down_sample(x) : | ||
| 120 | + return tf.layers.average_pooling2d(x, pool_size=3, strides=2, padding='SAME') | ||
| 121 | + | ||
| 122 | +def up_sample(x, scale_factor=2): | ||
| 123 | + _, h, w, _ = x.get_shape().as_list() | ||
| 124 | + new_size = [h * scale_factor, w * scale_factor] | ||
| 125 | + return tf.image.resize_nearest_neighbor(x, size=new_size) | ||
| 126 | + | ||
| 127 | +def adaptive_avg_pooling(x): | ||
| 128 | + # global average pooling | ||
| 129 | + gap = tf.reduce_mean(x, axis=[1, 2], keep_dims=True) | ||
| 130 | + | ||
| 131 | + return gap | ||
| 132 | + | ||
| 133 | +################################################################################## | ||
| 134 | +# Activation function | ||
| 135 | +################################################################################## | ||
| 136 | + | ||
| 137 | +def lrelu(x, alpha=0.01): | ||
| 138 | + # pytorch alpha is 0.01 | ||
| 139 | + return tf.nn.leaky_relu(x, alpha) | ||
| 140 | + | ||
| 141 | + | ||
| 142 | +def relu(x): | ||
| 143 | + return tf.nn.relu(x) | ||
| 144 | + | ||
| 145 | + | ||
| 146 | +def tanh(x): | ||
| 147 | + return tf.tanh(x) | ||
| 148 | + | ||
| 149 | +################################################################################## | ||
| 150 | +# Normalization function | ||
| 151 | +################################################################################## | ||
| 152 | + | ||
| 153 | +def adaptive_instance_norm(content, gamma, beta, epsilon=1e-5): | ||
| 154 | + # gamma, beta = style_mean, style_std from MLP | ||
| 155 | + | ||
| 156 | + c_mean, c_var = tf.nn.moments(content, axes=[1, 2], keep_dims=True) | ||
| 157 | + c_std = tf.sqrt(c_var + epsilon) | ||
| 158 | + | ||
| 159 | + return gamma * ((content - c_mean) / c_std) + beta | ||
| 160 | + | ||
| 161 | + | ||
| 162 | +def instance_norm(x, scope='instance_norm'): | ||
| 163 | + return tf_contrib.layers.instance_norm(x, | ||
| 164 | + epsilon=1e-05, | ||
| 165 | + center=True, scale=True, | ||
| 166 | + scope=scope) | ||
| 167 | + | ||
| 168 | +def layer_norm(x, scope='layer_norm') : | ||
| 169 | + return tf_contrib.layers.layer_norm(x, | ||
| 170 | + center=True, scale=True, | ||
| 171 | + scope=scope) | ||
| 172 | + | ||
| 173 | +################################################################################## | ||
| 174 | +# Loss function | ||
| 175 | +################################################################################## | ||
| 176 | + | ||
| 177 | +""" | ||
| 178 | + | ||
| 179 | +Author use LSGAN | ||
| 180 | +For LSGAN, multiply each of G and D by 0.5. | ||
| 181 | +However, MUNIT authors did not do this. | ||
| 182 | + | ||
| 183 | +""" | ||
| 184 | + | ||
| 185 | +def discriminator_loss(type, real, fake): | ||
| 186 | + n_scale = len(real) | ||
| 187 | + loss = [] | ||
| 188 | + | ||
| 189 | + real_loss = 0 | ||
| 190 | + fake_loss = 0 | ||
| 191 | + | ||
| 192 | + for i in range(n_scale) : | ||
| 193 | + if type == 'lsgan' : | ||
| 194 | + real_loss = tf.reduce_mean(tf.squared_difference(real[i], 1.0)) | ||
| 195 | + fake_loss = tf.reduce_mean(tf.square(fake[i])) | ||
| 196 | + | ||
| 197 | + if type == 'gan' : | ||
| 198 | + real_loss = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(labels=tf.ones_like(real[i]), logits=real[i])) | ||
| 199 | + fake_loss = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(labels=tf.zeros_like(fake[i]), logits=fake[i])) | ||
| 200 | + | ||
| 201 | + loss.append(real_loss + fake_loss) | ||
| 202 | + | ||
| 203 | + return sum(loss) | ||
| 204 | + | ||
| 205 | + | ||
| 206 | +def generator_loss(type, fake): | ||
| 207 | + n_scale = len(fake) | ||
| 208 | + loss = [] | ||
| 209 | + | ||
| 210 | + fake_loss = 0 | ||
| 211 | + | ||
| 212 | + for i in range(n_scale) : | ||
| 213 | + if type == 'lsgan' : | ||
| 214 | + fake_loss = tf.reduce_mean(tf.squared_difference(fake[i], 1.0)) | ||
| 215 | + | ||
| 216 | + if type == 'gan' : | ||
| 217 | + fake_loss = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(labels=tf.ones_like(fake[i]), logits=fake[i])) | ||
| 218 | + | ||
| 219 | + loss.append(fake_loss) | ||
| 220 | + | ||
| 221 | + | ||
| 222 | + return sum(loss) | ||
| 223 | + | ||
| 224 | + | ||
| 225 | +def L1_loss(x, y): | ||
| 226 | + loss = tf.reduce_mean(tf.abs(x - y)) | ||
| 227 | + | ||
| 228 | + return loss | ||
| 229 | + | ||
| 230 | +def regularization_loss(scope_name) : | ||
| 231 | + """ | ||
| 232 | + If you want to use "Regularization" | ||
| 233 | + g_loss += regularization_loss('generator') | ||
| 234 | + d_loss += regularization_loss('discriminator') | ||
| 235 | + """ | ||
| 236 | + collection_regularization = tf.get_collection(tf.GraphKeys.REGULARIZATION_LOSSES) | ||
| 237 | + | ||
| 238 | + loss = [] | ||
| 239 | + for item in collection_regularization : | ||
| 240 | + if scope_name in item.name : | ||
| 241 | + loss.append(item) | ||
| 242 | + | ||
| 243 | + return tf.reduce_sum(loss) | ||
| @@ -0,0 +1,225 @@ | |||
| 1 | +#!/bin/bash | ||
| 2 | + | ||
| 3 | +########################################################## | ||
| 4 | +#########第3行 至 100行,请一定不要、不要、不要修改########## | ||
| 5 | +#########第3行 至 100行,请一定不要、不要、不要修改########## | ||
| 6 | +#########第3行 至 100行,请一定不要、不要、不要修改########## | ||
| 7 | +########################################################## | ||
| 8 | +# shell脚本所在路径 | ||
| 9 | +cur_path=`echo $(cd $(dirname $0);pwd)` | ||
| 10 | + | ||
| 11 | +# 判断当前shell是否是performance | ||
| 12 | +perf_flag=`echo $0 | grep performance | wc -l` | ||
| 13 | + | ||
| 14 | +# 当前执行网络的名称 | ||
| 15 | +Network=`echo $(cd $(dirname $0);pwd) | awk -F"/" '{print $(NF-1)}'` | ||
| 16 | + | ||
| 17 | +export RANK_SIZE=1 | ||
| 18 | +export RANK_ID=0 | ||
| 19 | +export JOB_ID=10087 | ||
| 20 | + | ||
| 21 | +# 路径参数初始化 | ||
| 22 | +data_path="" | ||
| 23 | +output_path="" | ||
| 24 | + | ||
| 25 | +# 帮助信息,不需要修改 | ||
| 26 | +if [[ $1 == --help || $1 == -h ]];then | ||
| 27 | + echo"usage:./train_performance_1P.sh <args>" | ||
| 28 | + echo " " | ||
| 29 | + echo "parameter explain: | ||
| 30 | + --data_path # dataset of training | ||
| 31 | + --output_path # output of training | ||
| 32 | + --train_steps # max_step for training | ||
| 33 | + --train_epochs # max_epoch for training | ||
| 34 | + --batch_size # batch size | ||
| 35 | + -h/--help show help message | ||
| 36 | + " | ||
| 37 | + exit 1 | ||
| 38 | +fi | ||
| 39 | + | ||
| 40 | +# 参数校验,不需要修改 | ||
| 41 | +for para in $* | ||
| 42 | +do | ||
| 43 | + if [[ $para == --data_path* ]];then | ||
| 44 | + data_path=`echo ${para#*=}` | ||
| 45 | + elif [[ $para == --output_path* ]];then | ||
| 46 | + output_path=`echo ${para#*=}` | ||
| 47 | + elif [[ $para == --train_steps* ]];then | ||
| 48 | + train_steps=`echo ${para#*=}` | ||
| 49 | + elif [[ $para == --train_epochs* ]];then | ||
| 50 | + train_epochs=`echo ${para#*=}` | ||
| 51 | + elif [[ $para == --batch_size* ]];then | ||
| 52 | + batch_size=`echo ${para#*=}` | ||
| 53 | + fi | ||
| 54 | +done | ||
| 55 | + | ||
| 56 | +# 校验是否传入data_path,不需要修改 | ||
| 57 | +# data_path="./dataset/edges2shoes/train" | ||
| 58 | +if [[ $data_path == "" ]];then | ||
| 59 | + echo "[Error] para \"data_path\" must be config" | ||
| 60 | + exit 1 | ||
| 61 | +fi | ||
| 62 | + | ||
| 63 | +# 校验是否传入output_path,不需要修改 | ||
| 64 | +if [[ $output_path == "" ]];then | ||
| 65 | + output_path="./test/output/${ASCEND_DEVICE_ID}" | ||
| 66 | +fi | ||
| 67 | + | ||
| 68 | +# 设置打屏日志文件名,请保留,文件名为${print_log} | ||
| 69 | +print_log="./test/output/${ASCEND_DEVICE_ID}/train_${ASCEND_DEVICE_ID}.log" | ||
| 70 | +modelarts_flag=`cat /etc/passwd |grep ma-user` | ||
| 71 | +if [ x"${modelarts_flag}" != x ]; | ||
| 72 | +then | ||
| 73 | + echo "running with modelarts_flag..." | ||
| 74 | + print_log_name=`ls /home/ma-user/modelarts/log/ | grep proc-rank` | ||
| 75 | + print_log="/home/ma-user/modelarts/log/${print_log_name}" | ||
| 76 | +fi | ||
| 77 | +echo "### get your log here : ${print_log}" | ||
| 78 | + | ||
| 79 | +CaseName="" | ||
| 80 | +function get_casename() | ||
| 81 | +{ | ||
| 82 | + if [ x"${perf_flag}" = x1 ]; | ||
| 83 | + then | ||
| 84 | + CaseName=${Network}_bs${batch_size}_${RANK_SIZE}'p'_'perf' | ||
| 85 | + else | ||
| 86 | + CaseName=${Network}_bs${batch_size}_${RANK_SIZE}'p'_'acc' | ||
| 87 | + fi | ||
| 88 | +} | ||
| 89 | + | ||
| 90 | +# 跳转到code目录 | ||
| 91 | +cd ${cur_path}/../ | ||
| 92 | +rm -rf ./test/output/${ASCEND_DEVICE_ID} | ||
| 93 | +mkdir -p ./test/output/${ASCEND_DEVICE_ID} | ||
| 94 | + | ||
| 95 | +# 训练开始时间记录,不需要修改 | ||
| 96 | +start_time=$(date +%s) | ||
| 97 | +########################################################## | ||
| 98 | +#########第3行 至 100行,请一定不要、不要、不要修改########## | ||
| 99 | +#########第3行 至 100行,请一定不要、不要、不要修改########## | ||
| 100 | +#########第3行 至 100行,请一定不要、不要、不要修改########## | ||
| 101 | +########################################################## | ||
| 102 | + | ||
| 103 | +#========================================================= | ||
| 104 | +#========================================================= | ||
| 105 | +#========训练执行命令,需要根据您的网络进行修改============== | ||
| 106 | +#========================================================= | ||
| 107 | +#========================================================= | ||
| 108 | +# 基础参数,需要模型审视修改 | ||
| 109 | +# 您的训练数据集在${data_path}路径下,请直接使用这个变量获取 | ||
| 110 | +# 您的训练输出目录在${output_path}路径下,请直接使用这个变量获取 | ||
| 111 | +# 您的其他基础参数,可以自定义增加,但是batch_size请保留,并且设置正确的值 | ||
| 112 | + | ||
| 113 | +# batch_size=64 | ||
| 114 | + | ||
| 115 | +# if [ x"${modelarts_flag}" != x ]; | ||
| 116 | +# then | ||
| 117 | +# python3.7 ./LeNet.py --data_path=${data_path} --output_path=${output_path} | ||
| 118 | +# else | ||
| 119 | +# python3.7 ./LeNet.py --data_path=${data_path} --output_path=${output_path} 1>${print_log} 2>&1 | ||
| 120 | +# fi | ||
| 121 | + | ||
| 122 | +# # 性能相关数据计算 | ||
| 123 | +# StepTime=`grep "sec/step :" ${print_log} | tail -n 10 | awk '{print $NF}' | awk '{sum+=$1} END {print sum/NR}'` | ||
| 124 | +# FPS=`awk 'BEGIN{printf "%.2f\n", '${batch_size}'/'${StepTime}'}'` | ||
| 125 | + | ||
| 126 | +# # 精度相关数据计算 | ||
| 127 | +# train_accuracy=`grep "Final Accuracy accuracy" ${print_log} | awk '{print $NF}'` | ||
| 128 | +# # 提取所有loss打印信息 | ||
| 129 | +# grep "loss :" ${print_log} | awk -F ":" '{print $4}' | awk -F "-" '{print $1}' > ./test/output/${ASCEND_DEVICE_ID}/my_output_loss.txt | ||
| 130 | +train_epochs=1 | ||
| 131 | +train_steps=100000 | ||
| 132 | +batch_size=1 | ||
| 133 | +epoch=1 | ||
| 134 | + | ||
| 135 | +if [ x"${modelarts_flag}" != x ]; | ||
| 136 | +then | ||
| 137 | + ASCEND_VISIBLE_DEVICES=0 python3.7 ./main.py --data_path=${data_path} --phase train \ | ||
| 138 | + --epoch ${epoch} \ | ||
| 139 | + --iteration ${train_steps} \ | ||
| 140 | + --result=${output_path} \ | ||
| 141 | + --batch_size ${batch_size} | ||
| 142 | +else | ||
| 143 | + ASCEND_VISIBLE_DEVICES=0 python3.7 ./main.py --data_path=${data_path} --phase train \ | ||
| 144 | + --epoch ${epoch} \ | ||
| 145 | + --iteration ${train_steps} \ | ||
| 146 | + --result=${output_path} \ | ||
| 147 | + --batch_size ${batch_size} 1>${print_log} 2>&1 | ||
| 148 | +fi | ||
| 149 | + | ||
| 150 | +# 性能相关数据计算 | ||
| 151 | +#StepTime=`grep "sec/step :" ${print_log} | tail -n 10 | awk '{print $NF}' | awk '{sum+=$1} END {print sum/NR}'` | ||
| 152 | +step0=`grep time ${print_log} | awk -F"time: " '{print $2}' | awk -F" " 'END{print $1}'` | ||
| 153 | +step1=`grep time ${print_log} | awk -F"time: " '{print $2}' | awk -F" " '{print $1}' | tail -2 | head -1` | ||
| 154 | +StepTime=`awk 'BEGIN{printf "%.4f",('${step0}'-'${step1}')}'` | ||
| 155 | +FPS=`awk 'BEGIN{printf "%.2f\n", '${batch_size}'/'${StepTime}'}'` | ||
| 156 | + | ||
| 157 | +# # 精度相关数据计算 | ||
| 158 | +# train_accuracy=`grep "Final Accuracy accuracy" ${print_log} | awk '{print $NF}'` | ||
| 159 | +# # 提取所有loss打印信息 | ||
| 160 | +# grep "loss :" ${print_log} | awk -F ":" '{print $4}' | awk -F "-" '{print $1}' > ./test/output/${ASCEND_DEVICE_ID}/my_output_loss.txt | ||
| 161 | +# 精度相关数据计算 | ||
| 162 | +# train_accuracy=`grep "Final Accuracy accuracy" ${print_log} | awk '{print $NF}'` | ||
| 163 | +train_accuracy="None" | ||
| 164 | +# 提取所有loss打印信息 | ||
| 165 | +#grep "loss :" ${print_log} | awk -F ":" '{print $4}' | awk -F "-" '{print $1}' > ./test/output/${ASCEND_DEVICE_ID}/my_output_loss.txt | ||
| 166 | +grep d_loss ${print_log} | awk -F"d_loss: " '{print $2}' > ./test/output/${ASCEND_DEVICE_ID}/my_output_loss.txt | ||
| 167 | +grep g_loss ${print_log} | awk -F"g_loss: " '{print $2}' > ./test/output/${ASCEND_DEVICE_ID}/my_output_loss.txt | ||
| 168 | + | ||
| 169 | + | ||
| 170 | +########################################################### | ||
| 171 | +#########后面的所有内容请不要修改########################### | ||
| 172 | +#########后面的所有内容请不要修改########################### | ||
| 173 | +#########后面的所有内容请不要修改########################### | ||
| 174 | +########################################################### | ||
| 175 | + | ||
| 176 | +# 判断本次执行是否正确使用Ascend NPU | ||
| 177 | +tf_flag=`echo ${Network} | grep TensorFlow | wc -l` | ||
| 178 | +use_npu_flag=`grep "The model has been compiled on the Ascend AI processor" ${print_log} | wc -l` | ||
| 179 | +if [ x"${use_npu_flag}" == x0 -a x"${tf_flag}" == x1 ]; | ||
| 180 | +then | ||
| 181 | + echo "------------------ ERROR NOTICE START ------------------" | ||
| 182 | + echo "ERROR, your task haven't used Ascend NPU, please check your npu Migration." | ||
| 183 | + echo "------------------ ERROR NOTICE END------------------" | ||
| 184 | +else | ||
| 185 | + echo "------------------ INFO NOTICE START------------------" | ||
| 186 | + echo "INFO, your task have used Ascend NPU, please check your result." | ||
| 187 | + echo "------------------ INFO NOTICE END------------------" | ||
| 188 | +fi | ||
| 189 | + | ||
| 190 | +# 获取最终的casename,请保留,case文件名为${CaseName} | ||
| 191 | +get_casename | ||
| 192 | + | ||
| 193 | +# 重命名loss文件 | ||
| 194 | +if [ -f ./test/output/${ASCEND_DEVICE_ID}/my_output_loss.txt ]; | ||
| 195 | +then | ||
| 196 | + mv ./test/output/${ASCEND_DEVICE_ID}/my_output_loss.txt ./test/output/${ASCEND_DEVICE_ID}/${CaseName}_loss.txt | ||
| 197 | +fi | ||
| 198 | + | ||
| 199 | +# 训练端到端耗时 | ||
| 200 | +end_time=$(date +%s) | ||
| 201 | +e2e_time=$(( $end_time - $start_time )) | ||
| 202 | + | ||
| 203 | +echo "------------------ Final result ------------------" | ||
| 204 | +# 输出性能FPS/单step耗时/端到端耗时 | ||
| 205 | +echo "Final Performance images/sec : $FPS" | ||
| 206 | +echo "Final Performance sec/step : $StepTime" | ||
| 207 | +echo "E2E Training Duration sec : $e2e_time" | ||
| 208 | + | ||
| 209 | +# 输出训练精度 | ||
| 210 | +echo "Final Train Accuracy : ${train_accuracy}" | ||
| 211 | + | ||
| 212 | +# 最后一个迭代loss值,不需要修改 | ||
| 213 | +ActualLoss=(`awk 'END {print $NF}' $cur_path/output/$ASCEND_DEVICE_ID/${CaseName}_loss.txt`) | ||
| 214 | + | ||
| 215 | +#关键信息打印到${CaseName}.log中,不需要修改 | ||
| 216 | +echo "Network = ${Network}" > $cur_path/output/$ASCEND_DEVICE_ID/${CaseName}.log | ||
| 217 | +echo "RankSize = ${RANK_SIZE}" >> $cur_path/output/$ASCEND_DEVICE_ID/${CaseName}.log | ||
| 218 | +echo "BatchSize = ${batch_size}" >> $cur_path/output/$ASCEND_DEVICE_ID/${CaseName}.log | ||
| 219 | +echo "DeviceType = `uname -m`" >> $cur_path/output/$ASCEND_DEVICE_ID/${CaseName}.log | ||
| 220 | +echo "CaseName = ${CaseName}" >> $cur_path/output/$ASCEND_DEVICE_ID/${CaseName}.log | ||
| 221 | +echo "ActualFPS = ${FPS}" >> $cur_path/output/$ASCEND_DEVICE_ID/${CaseName}.log | ||
| 222 | +echo "TrainingTime = ${StepTime}" >> $cur_path/output/$ASCEND_DEVICE_ID/${CaseName}.log | ||
| 223 | +echo "ActualLoss = ${ActualLoss}" >> $cur_path/output/$ASCEND_DEVICE_ID/${CaseName}.log | ||
| 224 | +echo "E2ETrainingTime = ${e2e_time}" >> $cur_path/output/$ASCEND_DEVICE_ID/${CaseName}.log | ||
| 225 | +echo "TrainAccuracy = ${train_accuracy}" >> $cur_path/output/$ASCEND_DEVICE_ID/${CaseName}.log | ||
| @@ -0,0 +1,207 @@ | |||
| 1 | +#!/bin/bash | ||
| 2 | + | ||
| 3 | +########################################################## | ||
| 4 | +#########第3行 至 100行,请一定不要、不要、不要修改########## | ||
| 5 | +#########第3行 至 100行,请一定不要、不要、不要修改########## | ||
| 6 | +#########第3行 至 100行,请一定不要、不要、不要修改########## | ||
| 7 | +########################################################## | ||
| 8 | +# shell脚本所在路径 | ||
| 9 | +cur_path=`echo $(cd $(dirname $0);pwd)` | ||
| 10 | + | ||
| 11 | +output_path="./edges2shoes_npu_allow_fp32_to_fp16" | ||
| 12 | +# 判断当前shell是否是performance | ||
| 13 | +perf_flag=`echo $0 | grep performance | wc -l` | ||
| 14 | + | ||
| 15 | +# 当前执行网络的名称 | ||
| 16 | +Network=`echo $(cd $(dirname $0);pwd) | awk -F"/" '{print $(NF-1)}'` | ||
| 17 | + | ||
| 18 | +export RANK_SIZE=1 | ||
| 19 | +export RANK_ID=0 | ||
| 20 | +export JOB_ID=10087 | ||
| 21 | + | ||
| 22 | +# 路径参数初始化 | ||
| 23 | +data_path="" | ||
| 24 | +output_path="" | ||
| 25 | + | ||
| 26 | +# 帮助信息,不需要修改 | ||
| 27 | +if [[ $1 == --help || $1 == -h ]];then | ||
| 28 | + echo"usage:./train_performance_1P.sh <args>" | ||
| 29 | + echo " " | ||
| 30 | + echo "parameter explain: | ||
| 31 | + --data_path # dataset of training | ||
| 32 | + --output_path # output of training | ||
| 33 | + --train_steps # max_step for training | ||
| 34 | + --train_epochs # max_epoch for training | ||
| 35 | + --batch_size # batch size | ||
| 36 | + -h/--help show help message | ||
| 37 | + " | ||
| 38 | + exit 1 | ||
| 39 | +fi | ||
| 40 | + | ||
| 41 | +# 参数校验,不需要修改 | ||
| 42 | +for para in $* | ||
| 43 | +do | ||
| 44 | + if [[ $para == --data_path* ]];then | ||
| 45 | + data_path=`echo ${para#*=}` | ||
| 46 | + elif [[ $para == --output_path* ]];then | ||
| 47 | + output_path=`echo ${para#*=}` | ||
| 48 | + elif [[ $para == --train_steps* ]];then | ||
| 49 | + train_steps=`echo ${para#*=}` | ||
| 50 | + elif [[ $para == --train_epochs* ]];then | ||
| 51 | + train_epochs=`echo ${para#*=}` | ||
| 52 | + elif [[ $para == --batch_size* ]];then | ||
| 53 | + batch_size=`echo ${para#*=}` | ||
| 54 | + fi | ||
| 55 | +done | ||
| 56 | + | ||
| 57 | +# 校验是否传入data_path,不需要修改 | ||
| 58 | +# data_path="./dataset/edges2shoes/train" | ||
| 59 | +if [[ $data_path == "" ]];then | ||
| 60 | + echo "[Error] para \"data_path\" must be config" | ||
| 61 | + exit 1 | ||
| 62 | +fi | ||
| 63 | + | ||
| 64 | +# 校验是否传入output_path,不需要修改 | ||
| 65 | +if [[ $output_path == "" ]];then | ||
| 66 | + output_path="./test/output/${ASCEND_DEVICE_ID}" | ||
| 67 | +fi | ||
| 68 | + | ||
| 69 | +# 设置打屏日志文件名,请保留,文件名为${print_log} | ||
| 70 | +print_log="./test/output/${ASCEND_DEVICE_ID}/train_${ASCEND_DEVICE_ID}.log" | ||
| 71 | +modelarts_flag=`cat /etc/passwd |grep ma-user` | ||
| 72 | +if [ x"${modelarts_flag}" != x ]; | ||
| 73 | +then | ||
| 74 | + echo "running with modelarts..." | ||
| 75 | + print_log_name=`ls /home/ma-user/modelarts/log/ | grep proc-rank` | ||
| 76 | + print_log="/home/ma-user/modelarts/log/${print_log_name}" | ||
| 77 | +fi | ||
| 78 | +echo "### get your log here : ${print_log}" | ||
| 79 | + | ||
| 80 | +CaseName="" | ||
| 81 | +function get_casename() | ||
| 82 | +{ | ||
| 83 | + if [ x"${perf_flag}" = x1 ]; | ||
| 84 | + then | ||
| 85 | + CaseName=${Network}_bs${batch_size}_${RANK_SIZE}'p'_'perf' | ||
| 86 | + else | ||
| 87 | + CaseName=${Network}_bs${batch_size}_${RANK_SIZE}'p'_'acc' | ||
| 88 | + fi | ||
| 89 | +} | ||
| 90 | + | ||
| 91 | +# 跳转到code目录 | ||
| 92 | +cd ${cur_path}/../ | ||
| 93 | +rm -rf ./test/output/${ASCEND_DEVICE_ID} | ||
| 94 | +mkdir -p ./test/output/${ASCEND_DEVICE_ID} | ||
| 95 | + | ||
| 96 | +# 训练开始时间记录,不需要修改 | ||
| 97 | +start_time=$(date +%s) | ||
| 98 | +########################################################## | ||
| 99 | +#########第3行 至 100行,请一定不要、不要、不要修改########## | ||
| 100 | +#########第3行 至 100行,请一定不要、不要、不要修改########## | ||
| 101 | +#########第3行 至 100行,请一定不要、不要、不要修改########## | ||
| 102 | +########################################################## | ||
| 103 | + | ||
| 104 | +#========================================================= | ||
| 105 | +#========================================================= | ||
| 106 | +#========训练执行命令,需要根据您的网络进行修改============== | ||
| 107 | +#========================================================= | ||
| 108 | +#========================================================= | ||
| 109 | +# 基础参数,需要模型审视修改 | ||
| 110 | +# 您的训练数据集在${data_path}路径下,请直接使用这个变量获取 | ||
| 111 | +# 您的训练输出目录在${output_path}路径下,请直接使用这个变量获取 | ||
| 112 | +# 您的其他基础参数,可以自定义增加,但是batch_size请保留,并且设置正确的值 | ||
| 113 | +train_epochs=1 | ||
| 114 | +train_steps=100000 | ||
| 115 | +batch_size=1 | ||
| 116 | +epoch=1 | ||
| 117 | + | ||
| 118 | +if [ x"${modelarts_flag}" != x ]; | ||
| 119 | +then | ||
| 120 | + python3.7 ./main.py --data_path=${data_path} --phase train \ | ||
| 121 | + --epoch ${epoch} \ | ||
| 122 | + --iteration ${train_steps} \ | ||
| 123 | + --result=${output_path} \ | ||
| 124 | + --batch_size ${batch_size} | ||
| 125 | +else | ||
| 126 | + python3.7 ./main.py --data_path=${data_path} --phase train \ | ||
| 127 | + --epoch ${epoch} \ | ||
| 128 | + --iteration ${train_steps} \ | ||
| 129 | + --result=${output_path} \ | ||
| 130 | + --batch_size ${batch_size} 1>${print_log} 2>&1 | ||
| 131 | +fi | ||
| 132 | + | ||
| 133 | +# 性能相关数据计算 | ||
| 134 | +#StepTime=`grep "sec/step :" ${print_log} | tail -n 10 | awk '{print $NF}' | awk '{sum+=$1} END {print sum/NR}'` | ||
| 135 | +step0=`grep time ${print_log} | awk -F"time: " '{print $2}' | awk -F" " 'END{print $1}'` | ||
| 136 | +step1=`grep time ${print_log} | awk -F"time: " '{print $2}' | awk -F" " '{print $1}' | tail -2 | head -1` | ||
| 137 | +StepTime=`awk 'BEGIN{printf "%.4f",('${step0}'-'${step1}')}'` | ||
| 138 | +FPS=`awk 'BEGIN{printf "%.2f\n", '${batch_size}'/'${StepTime}'}'` | ||
| 139 | + | ||
| 140 | +# # 精度相关数据计算 | ||
| 141 | +# train_accuracy=`grep "Final Accuracy accuracy" ${print_log} | awk '{print $NF}'` | ||
| 142 | +# # 提取所有loss打印信息 | ||
| 143 | +# grep "loss :" ${print_log} | awk -F ":" '{print $4}' | awk -F "-" '{print $1}' > ./test/output/${ASCEND_DEVICE_ID}/my_output_loss.txt | ||
| 144 | +# 精度相关数据计算 | ||
| 145 | +# train_accuracy=`grep "Final Accuracy accuracy" ${print_log} | awk '{print $NF}'` | ||
| 146 | +train_accuracy="None" | ||
| 147 | +# 提取所有loss打印信息 | ||
| 148 | +#grep "loss :" ${print_log} | awk -F ":" '{print $4}' | awk -F "-" '{print $1}' > ./test/output/${ASCEND_DEVICE_ID}/my_output_loss.txt | ||
| 149 | +grep d_loss ${print_log} | awk -F"d_loss: " '{print $2}' > ./test/output/${ASCEND_DEVICE_ID}/my_output_loss.txt | ||
| 150 | +grep g_loss ${print_log} | awk -F"g_loss: " '{print $2}' > ./test/output/${ASCEND_DEVICE_ID}/my_output_loss.txt | ||
| 151 | + | ||
| 152 | + | ||
| 153 | +########################################################### | ||
| 154 | +#########后面的所有内容请不要修改########################### | ||
| 155 | +#########后面的所有内容请不要修改########################### | ||
| 156 | +#########后面的所有内容请不要修改########################### | ||
| 157 | +########################################################### | ||
| 158 | + | ||
| 159 | +# 判断本次执行是否正确使用Ascend NPU | ||
| 160 | +tf_flag=`echo ${Network} | grep TensorFlow | wc -l` | ||
| 161 | +use_npu_flag=`grep "The model has been compiled on the Ascend AI processor" ${print_log} | wc -l` | ||
| 162 | +if [ x"${use_npu_flag}" == x0 -a x"${tf_flag}" == x1 ]; | ||
| 163 | +then | ||
| 164 | + echo "------------------ ERROR NOTICE START ------------------" | ||
| 165 | + echo "ERROR, your task haven't used Ascend NPU, please check your npu Migration." | ||
| 166 | + echo "------------------ ERROR NOTICE END------------------" | ||
| 167 | +else | ||
| 168 | + echo "------------------ INFO NOTICE START------------------" | ||
| 169 | + echo "INFO, your task have used Ascend NPU, please check your result." | ||
| 170 | + echo "------------------ INFO NOTICE END------------------" | ||
| 171 | +fi | ||
| 172 | + | ||
| 173 | +# 获取最终的casename,请保留,case文件名为${CaseName} | ||
| 174 | +get_casename | ||
| 175 | + | ||
| 176 | +# 重命名loss文件 | ||
| 177 | +if [ -f ./test/output/${ASCEND_DEVICE_ID}/my_output_loss.txt ]; | ||
| 178 | +then | ||
| 179 | + mv ./test/output/${ASCEND_DEVICE_ID}/my_output_loss.txt ./test/output/${ASCEND_DEVICE_ID}/${CaseName}_loss.txt | ||
| 180 | +fi | ||
| 181 | + | ||
| 182 | +# 训练端到端耗时 | ||
| 183 | +end_time=$(date +%s) | ||
| 184 | +e2e_time=$(( $end_time - $start_time )) | ||
| 185 | + | ||
| 186 | +echo "------------------ Final result ------------------" | ||
| 187 | +# 输出性能FPS/单step耗时/端到端耗时 | ||
| 188 | +echo "Final Performance images/sec : $FPS" | ||
| 189 | +echo "Final Performance sec/step : $StepTime" | ||
| 190 | +echo "E2E Training Duration sec : $e2e_time" | ||
| 191 | + | ||
| 192 | +# 输出训练精度 | ||
| 193 | +echo "Final Train Accuracy : ${train_accuracy}" | ||
| 194 | + | ||
| 195 | +# 最后一个迭代loss值,不需要修改 | ||
| 196 | +ActualLoss=(`awk 'END {print $NF}' $cur_path/output/$ASCEND_DEVICE_ID/${CaseName}_loss.txt`) | ||
| 197 | + | ||
| 198 | +#关键信息打印到${CaseName}.log中,不需要修改 | ||
| 199 | +echo "Network = ${Network}" > $cur_path/output/$ASCEND_DEVICE_ID/${CaseName}.log | ||
| 200 | +echo "RankSize = ${RANK_SIZE}" >> $cur_path/output/$ASCEND_DEVICE_ID/${CaseName}.log | ||
| 201 | +echo "BatchSize = ${batch_size}" >> $cur_path/output/$ASCEND_DEVICE_ID/${CaseName}.log | ||
| 202 | +echo "DeviceType = `uname -m`" >> $cur_path/output/$ASCEND_DEVICE_ID/${CaseName}.log | ||
| 203 | +echo "CaseName = ${CaseName}" >> $cur_path/output/$ASCEND_DEVICE_ID/${CaseName}.log | ||
| 204 | +echo "ActualFPS = ${FPS}" >> $cur_path/output/$ASCEND_DEVICE_ID/${CaseName}.log | ||
| 205 | +echo "TrainingTime = ${StepTime}" >> $cur_path/output/$ASCEND_DEVICE_ID/${CaseName}.log | ||
| 206 | +echo "ActualLoss = ${ActualLoss}" >> $cur_path/output/$ASCEND_DEVICE_ID/${CaseName}.log | ||
| 207 | +echo "E2ETrainingTime = ${e2e_time}" >> $cur_path/output/$ASCEND_DEVICE_ID/${CaseName}.log | ||
| @@ -0,0 +1,145 @@ | |||
| 1 | +# Copyright 2017 The TensorFlow Authors. All Rights Reserved. | ||
| 2 | +# | ||
| 3 | +# Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 4 | +# you may not use this file except in compliance with the License. | ||
| 5 | +# You may obtain a copy of the License at | ||
| 6 | +# | ||
| 7 | +# http://www.apache.org/licenses/LICENSE-2.0 | ||
| 8 | +# | ||
| 9 | +# Unless required by applicable law or agreed to in writing, software | ||
| 10 | +# distributed under the License is distributed on an "AS IS" BASIS, | ||
| 11 | +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 12 | +# See the License for the specific language governing permissions and | ||
| 13 | +# limitations under the License. | ||
| 14 | +# ============================================================================ | ||
| 15 | +# Copyright 2021 Huawei Technologies Co., Ltd | ||
| 16 | +# | ||
| 17 | +# Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 18 | +# you may not use this file except in compliance with the License. | ||
| 19 | +# You may obtain a copy of the License at | ||
| 20 | +# | ||
| 21 | +# http://www.apache.org/licenses/LICENSE-2.0 | ||
| 22 | +# | ||
| 23 | +# Unless required by applicable law or agreed to in writing, software | ||
| 24 | +# distributed under the License is distributed on an "AS IS" BASIS, | ||
| 25 | +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 26 | +# See the License for the specific language governing permissions and | ||
| 27 | +# limitations under the License. | ||
| 28 | + | ||
| 29 | +from npu_bridge.npu_init import * | ||
| 30 | +import tensorflow as tf | ||
| 31 | +from tensorflow.contrib import slim | ||
| 32 | +from scipy import misc | ||
| 33 | +import os, random | ||
| 34 | +import numpy as np | ||
| 35 | +import imageio | ||
| 36 | +from skimage.transform import resize | ||
| 37 | + | ||
| 38 | +# https://people.eecs.berkeley.edu/~taesung_park/CycleGAN/datasets/ | ||
| 39 | +# https://people.eecs.berkeley.edu/~tinghuiz/projects/pix2pix/datasets/ | ||
| 40 | + | ||
| 41 | +class ImageData: | ||
| 42 | + | ||
| 43 | + def __init__(self, img_h, img_w, channels, augment_flag=False): | ||
| 44 | + self.img_h = img_h | ||
| 45 | + self.img_w = img_w | ||
| 46 | + self.channels = channels | ||
| 47 | + self.augment_flag = augment_flag | ||
| 48 | + | ||
| 49 | + def image_processing(self, filename): | ||
| 50 | + x = tf.read_file(filename) | ||
| 51 | + x_decode = tf.image.decode_jpeg(x, channels=self.channels) | ||
| 52 | + img = tf.image.resize_images(x_decode, [self.img_h, self.img_w]) | ||
| 53 | + img = tf.cast(img, tf.float32) / 127.5 - 1 | ||
| 54 | + | ||
| 55 | + if self.augment_flag : | ||
| 56 | + augment_size_h = self.img_h + (30 if self.img_h == 256 else 15) | ||
| 57 | + augment_size_w = self.img_w + (30 if self.img_w == 256 else 15) | ||
| 58 | + p = random.random() | ||
| 59 | + if p > 0.5: | ||
| 60 | + img = augmentation(img, augment_size_h, augment_size_w) | ||
| 61 | + | ||
| 62 | + return img | ||
| 63 | + | ||
| 64 | + | ||
| 65 | +def load_test_data(image_path, size_h=256, size_w=256): | ||
| 66 | + #img = misc.imread(image_path, mode='RGB') | ||
| 67 | + img = imageio.imread(image_path, pilmode= 'RGB') | ||
| 68 | + #img = misc.imresize(img, [size_h, size_w]) | ||
| 69 | + img = resize(img, output_shape=(size_h, size_w)) | ||
| 70 | + img = np.expand_dims(img, axis=0) | ||
| 71 | + img = preprocessing(img) | ||
| 72 | + | ||
| 73 | + return img | ||
| 74 | + | ||
| 75 | +def preprocessing(x): | ||
| 76 | + x = x/127.5 - 1 # -1 ~ 1 | ||
| 77 | + return x | ||
| 78 | + | ||
| 79 | +def augmentation(image, aug_img_h, aug_img_w): | ||
| 80 | + seed = random.randint(0, 2 ** 31 - 1) | ||
| 81 | + ori_image_shape = tf.shape(image) | ||
| 82 | + image = tf.image.random_flip_left_right(image, seed=seed) | ||
| 83 | + image = tf.image.resize_images(image, [aug_img_h, aug_img_w]) | ||
| 84 | + image = tf.random_crop(image, ori_image_shape, seed=seed) | ||
| 85 | + return image | ||
| 86 | + | ||
| 87 | +def save_images(images, size, image_path): | ||
| 88 | + return imsave(inverse_transform(images), size, image_path) | ||
| 89 | + | ||
| 90 | +def inverse_transform(images): | ||
| 91 | + return (images+1.) / 2 | ||
| 92 | + | ||
| 93 | +def imsave(images, size, path): | ||
| 94 | + return imageio.imwrite(path, merge(images, size)) | ||
| 95 | + | ||
| 96 | +def merge(images, size): | ||
| 97 | + h, w = images.shape[1], images.shape[2] | ||
| 98 | + img = np.zeros((h * size[0], w * size[1], 3)) | ||
| 99 | + for idx, image in enumerate(images): | ||
| 100 | + i = idx % size[1] | ||
| 101 | + j = idx // size[1] | ||
| 102 | + img[h*j:h*(j+1), w*i:w*(i+1), :] = image | ||
| 103 | + | ||
| 104 | + return img | ||
| 105 | + | ||
| 106 | +def show_all_variables(): | ||
| 107 | + model_vars = tf.trainable_variables() | ||
| 108 | + slim.model_analyzer.analyze_vars(model_vars, print_info=True) | ||
| 109 | + | ||
| 110 | +def check_folder(log_dir): | ||
| 111 | + if not os.path.exists(log_dir): | ||
| 112 | + os.makedirs(log_dir) | ||
| 113 | + return log_dir | ||
| 114 | + | ||
| 115 | +def pytorch_xavier_weight_factor(gain=0.02, uniform=False) : | ||
| 116 | + | ||
| 117 | + if uniform : | ||
| 118 | + factor = gain * gain | ||
| 119 | + mode = 'FAN_AVG' | ||
| 120 | + else : | ||
| 121 | + factor = (gain * gain) / 1.3 | ||
| 122 | + mode = 'FAN_AVG' | ||
| 123 | + | ||
| 124 | + return factor, mode, uniform | ||
| 125 | + | ||
| 126 | +def pytorch_kaiming_weight_factor(a=0.0, activation_function='relu', uniform=False) : | ||
| 127 | + | ||
| 128 | + if activation_function == 'relu' : | ||
| 129 | + gain = np.sqrt(2.0) | ||
| 130 | + elif activation_function == 'leaky_relu' : | ||
| 131 | + gain = np.sqrt(2.0 / (1 + a ** 2)) | ||
| 132 | + elif activation_function =='tanh' : | ||
| 133 | + gain = 5.0 / 3 | ||
| 134 | + else : | ||
| 135 | + gain = 1.0 | ||
| 136 | + | ||
| 137 | + if uniform : | ||
| 138 | + factor = gain * gain | ||
| 139 | + mode = 'FAN_IN' | ||
| 140 | + else : | ||
| 141 | + factor = (gain * gain) / 1.3 | ||
| 142 | + mode = 'FAN_IN' | ||
| 143 | + | ||
| 144 | + return factor, mode, uniform | ||
| 145 | + | ||


无用的注释代码可以删除