¸ÅÊö
¶ÔÓÚ³ÌÐòÔ±À´½²£¬³ÉΪ½Ü³ö¿ªÔ´ÏîÄ¿µÄ¹±Ï×ÕßÊÇÒ»¼þÓÐÒâÒåµÄÊ£¬µ±È»£¬ÕâÒ²¾ø·ÇÒ×Ê¡£Èç¹ûÄãÕý´ÓÊÂÈ˹¤ÖÇÄÜÓйصŤ×÷£¬ÄÇôÄãÒ»¶¨Á˽âÖîÈçGoogle Tensorflow£¬Facebook PytorchÕâÑùµÄ¿ªÔ´ÏîÄ¿¡£ÏÂÃæÎÒÃǾÍ˵һ˵ÈçºÎ³ÉΪÕâЩ½Ü³öµÄ¿ªÔ´ÏîÄ¿µÄContributor¡£
×¼±¸
1.Ê×ÏÈÄã±ØÐë³ÉΪgithubµÄʹÓÃÕߣ¬²¢ÒѾÊìϤÁËgithubÉÏÍйܴúÂëµÄ»ù±¾Âß¼¡£
2.¶ÔÓڽܳöµÄ¿ªÔ´ÏîÄ¿£¬Ò»°ãÐèÒªÄãȥǩÊðÒ»·ÝContributor License Agreement(¼ò³ÆCLA)£¬ÀýÈçTensorflowÏîÄ¿£¬¸öÈËÇ©ÊðTF individual CLA£¬¹«Ë¾Ç©ÊðTF corporate CLA£¬PytorchÖеIJ¿·ÖÏîÄ¿ÔòÐèҪǩÊðFacebook CLA£¬ÕâÑùÄãµÄ´úÂë²ÅÔÊÐí±»½ÓÊÕ¡£
3.ÈÃÄã±àдµÄ´úÂë·ç¸ñ¸ü¹æ·¶£¬Ò»°ãµÄ¿ªÔ´ÏîÄ¿¶¼ÒªÇóΪGoogle Python Style£¬¼´Ê¹ÊÇPytorch¶¼ÊÇ×ñѸù淶£¬¸ü²»ÒªËµGoogle×Ô¼ÒµÄTensorflowÁË¡£
4.Äã¹±Ï׵ĴúÂëÍùÍùÓÉÀà»òÕߺ¯Êý¹¹³É(Îĵµ¹±Ï׳ýÍâ)£¬Òò´ËÄãÐèÒªµ¥Ôª²âÊÔ³ÌÐò£¬ËüºÍ´úÂë×¢ÊÍÒ»Ñù£¬ÊÇ´úÂë¹²Ïí¹ý³ÌÖбز»¿ÉÉÙµÄÒ»²¿·Ö¡£Ã»ÓÐËü£¬¼´Ê¹ÄãµÄ´úÂëÕýÈ·ÎÞÎóÒ²²»»á±»merge£¬×îÖÕ»¹ÊǻᱻҪÇóÌṩµ¥Ôª²âÊԽű¾¡£
5.ºÜ¶à¿ªÔ´ÏîĿҪÇóÄãµÄÿ¸öpy½Å±¾¶¼ÒªÒÔÐí¿ÉÖ¤Ê鿪ͷ£¬±ÈÈçTensorflow£¬ÕâÊÇËüµÄpythonÐí¿ÉÖ¤ÊéʾÀý: Python license example£¬µ±È»£¬ÕâºÜ¼òµ¥¡£
# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# =============================================================================
¹¤¾ß
½ÓÏÂÀ´ÎÒÃǽ«½éÉÜÏà¹Ø¹¤¾ßµÄʹÓã¬ËüÄܹ»ÓÐЧµÄ°ïÖúÎÒÃÇÀ´Íê³É¹±Ï×ǰµÄ×¼±¸¹¤×÷£¬±ÈÈ磺´úÂë¹æ·¶ºÍµ¥Ôª²âÊԵȡ£
´úÂë¹æ·¶¹¤¾ß
ΪÁËÂú×ã´úÂëÂú×ãGoogle StyleµÄÒªÇó£¬ÎÒÃÇÊ×ÏÈÐèÒªÒ»¸ö´úÂë¹æ·¶¼ì²â¹¤¾ß£¬ÕâÀïÎÒÃÇʹÓùٷ½ÍƼöµÄpylint¡£
°²×°:
ʹÓÃ:
# ʹÓÃpylint¼ì²â½Å±¾´úÂ룬ĬÈϽ«°´ÕÕPEP8±ê×¼
# ÕâÀïÎÒÃÇÐèÒªÖ¸¶¨ÅäÖÃÎļþ£¬¼´°´ÕÕGoogle Style±ê×¼
# myfile.py´ú±íÄãдºÃµÄpython½Å±¾Îļþ
pylint --rcfile=pylintrc myfile.py
pylintrcÄÚÈÝÇë²ÎÕÕ: pylintrc
ÓÖÒòΪÎÒÃdzõʼдµÄ´úÂëÍùÍùËæÒâÐÔ¹ýÇ¿£¬¿ÉÄÜÖ±½ÓÓÃpylintÐèÒªÐ޸ĵĵط½Ì«¶à£¬¿ÉÄܶÔÄãÓ×СµÄÐÄÁéÔì³ÉÖØ´´£¬Òò´Ë£¬ÕâÀïÒ²´øÀ´ºÜ¶à¿ªÔ´ÏîÄ¿ÍÆ¼öµÄÁíÍâÒ»¿î¹¤¾ß£ºblack£¬ËüÄܹ»Ö±½Ó°ïÄãÐ޸ĴúÂëÖгöÏֵĻù±¾ÎÊÌâ(ÈÔÈ»´æÔںܶàÎÊÌâÎÞ·¨±»Åж¨£¬ÐèҪʹÓÃpylint¼ì²â)¡£
°²×°:
ʹÓÃ:
# ÕâÀïµÄ-l´ú±í´úÂëµÄÿÐÐ×î´ó³¤¶È
# ĬÈÏÊÇ88£¬µ«ÊÇGoogle StyleÒªÇóΪ80
# Òò´ËÕâÀïÖ¸¶¨Îª80
black myfile.py -l 80
´úÂëÑùʽʾÀý:
def my_op(tensor_in, other_tensor_in, my_param, other_param=0.5,
output_collections=(), name=None):
"""My operation that adds two tensors with given coefficients.
Args:
tensor_in: `Tensor`, input tensor.
other_tensor_in: `Tensor`, same shape as `tensor_in`, other input tensor.
my_param: `float`, coefficient for `tensor_in`.
other_param: `float`, coefficient for `other_tensor_in`.
output_collections: `tuple` of `string`s, name of the collection to
collect result of this op.
name: `string`, name of the operation.
Returns:
`Tensor` of same shape as `tensor_in`, sum of input values with coefficients.
Example:
>>> my_op([1., 2.], [3., 4.], my_param=0.5, other_param=0.6,
output_collections=['MY_OPS'], name='add_t1t2')
[2.3, 3.4]
"""
with tf.name_scope(name or "my_op"):
tensor_in = tf.convert_to_tensor(tensor_in)
other_tensor_in = tf.convert_to_tensor(other_tensor_in)
result = my_param * tensor_in + other_param * other_tensor_in
tf.add_to_collection(output_collections, result)
return result
output = my_op(t1, t2, my_param=0.5, other_param=0.6,
output_collections=['MY_OPS'], name='add_t1t2')
µ¥Ôª²âÊÔ¹¤¾ß
·µ¥Ôª²âÊÔ¶ÔÓÚÍŶӿª·¢Ê®·ÖÖØÒª£¬ÊǼìÑé´úÂëÖÊÁ¿µÄÖØÒªÒÀ¾Ý£¬Òò´ËÄãµÄÿһ·ÝÍêÕûµÄ´úÂë¶¼ÒªÅ䱸µ¥Ôª²âÊԽű¾¡£ÕâÀïÎÒÃÇʹÓÃpythonÖ÷Á÷µÄµ¥Ôª²âÊÔ¹¤¾ßunittest¡£
· °²×°:
ʹÓÃ: ÕâÀïֻȥÑÝʾºËÐĵÄʹÓ÷½·¨£¬¸ü¾ßÌåµÄÄÚÈÝÇë²ÎÕÕunittestÎĵµ
# µ¼Èëunittest¹¤¾ß°ü
import unittest
# ÎÒÃÇÊ×ÏÈÒª½¨Á¢Ò»¸ö²âÊÔÀ࣬Ëü½«°üº¬ÄãËùÓÐÐèÒª½øÐвâÊԵĺ¯Êý
# Õâ¸öÀ಻ʹÓÃ__init__(self)£¬µ«¿ÉÒÔʹÓÃsetUp(self)À´¶¨Ò幫Óв¿·Ö
# ËüÐèÒª¼Ì³Ðunittest.TestCase, ÀàÃûÍùÍùÒ²½¨ÒéÒÔTest¿ªÍ·
class TestStringMethods(unittest.TestCase):
# ÀàµÄÀïÃæÒÀ´ÎÊÇÄãÐèÒª½øÐвâÊԵĺ¯Êý
# ÕâЩº¯Êý½¨ÒéÒÔtest_¿ªÍ·
# ÕâЩº¯ÊýÒ»°ãÇé¿ö²»ÉèÖòÎÊý£¬¶øÊÇÖ±½ÓÔÚº¯ÊýÖоßÌ廯ÐèÒªµÄ²ÎÊý
# µ±È»ÄãÒ²¿ÉÒÔÉèÖÃÔʼµÄ²ÎÊý£¬È»ºóÔÚÍⲿ¾ßÌ廯²ÎÊý²¢µ÷Óøú¯Êý
# ÔÚ²âÊÔº¯ÊýÖбØÐë´æÔÚassert...À´¶Ï¶¨²âÊÔ½á¹û
# ³£ÓõÄassert...°üÀ¨: assertEqual, assertTrue, assertFalse,
# assertRaises, assertIn, assertNotIn, assertIs, assertIsNot...
def test_upper(self,):
# ʹÓÃassertEqualÅжÏÁ½¸ö×Ö·û´®ÊÇ·ñÏàµÈ
self.assertEqual(
"foo".upper(), "FOO",
)
def test_isupper(self,):
# ʹÓÃassertTrue/False¶Ï¶¨Ìõ¼þÎªÕæ/¼Ù
self.assertTrue("FOO".isupper())
self.assertFalse("Foo".isupper())
def test_split(self,):
# É趨ÈÎÒâÊäÈë
s = "hello world"
# ʹÓÃassertIn¶Ï¶¨Áбí°üº¬¹ØÏµ
self.assertIn(
s.split(), [["hello", "world"]],
)
# ×¢Ò⣺ÕâÀïwith self.assertRaisesÀ´¶Ï¶¨Òì³£
with self.assertRaises(TypeError):
s.split("asd")
# ÕâÀïÊÇÖ÷º¯Êý£¬Èç¹ûʹÓÃpythonÔËÐиýű¾²âÊÔ£¬Ôò±ØÐë´æÔÚ
# Èç¹ûʹÓÃpytest(ºóÃæ»á½éÉÜ)£¬Ôò¿ÉÒÔÊ¡ÂÔ
if __name__ == "__main__":
# ʹÓÃunittest.mainÔËÐÐËùÓм̳Ðunittest.TestCaseµÄÀà
unittest.main()
×°ÊÎÆ÷µÄʹÓÃ: unittest×ʹÓ÷½·¨Ö®Ò»¾ÍÊÇÀà/º¯ÊýµÄ×°ÊÎÆ÷¡£
# ¶ÔÓÚÒ»Ð©ÌØÊâÐèÒªÇ¿ÖÆÌø¹ýµÄ²âÊÔµÄÀà/º¯ÊýʹÓÃÏ·½×°ÊÎÆ÷£¬µ«Äã±ØÐë˵Ã÷ÔÒò
# @unittest.skip("³¤µÃ̫˧£¬²»ÐèÒª²âÊÔ£¬¸øÎÒÌø¹ý£¡")
# Èç¹ûÌõ¼þÎªÕæ£¬Ôò¸Ã²âÊÔ±»Ç¿ÖÆÌø¹ý¡£±ÈÈ磺¼ì²âGPUÊÇ·ñ¿ÉÓÃ
# @unittest.skipIf(TEST_CUDA, "CUDA available")
# ³ý·ÇÌõ¼þÎªÕæ£¬·ñÔò¸Ã²âÊÔ±»Ç¿ÖÆÌø¹ý¡£±ÈÈç: ¼ì²âijЩÒÀÀµ°üÊÇ·ñ°²×°
# @unittest.skipUnless(has_unittest, "unittest dependencies are not installed")
# º¯ÊýÒì³£²âÊԵıí´ï·½Ê½£¬º¯Êý³öÏÖÒì³£Ôò²âÊÔͨ¹ý£¬±È֮ǰ˵µÄÄÚ²¿Òì³£Á£¶È¸ü´ó
# @unittest.expectedFailure
import torch
try:
import unittest
except ImportError:
has_unittest = False
else:
has_unittest = True
if torch.cuda.is_available():
TEST_CUDA = True
else:
TEST_CUDA = False
# Ìõ¼þÎªÕæ£¬²»Ìø¹ý
@unittest.skipUnless(has_unittest, "unittest dependencies are not installed")
# Ìõ¼þÎªÕæ£¬Ìø¹ý£»Ìõ¼þΪ¼Ù£¬²»Ìø¹ý
@unittest.skipIf(TEST_CUDA, "CUDA available")
class TestStringMethods(unittest.TestCase):
def test_upper(self,):
self.assertEqual(
"foo".upper(), "FOO",
)
@unittest.skip("³¤µÃ̫˧£¬²»ÐèÒª²âÊÔ£¬¸øÎÒÌø¹ý£¡")
def test_isupper(self,):
self.assertTrue("FOO".isupper())
self.assertFalse("Foo".isupper())
@unittest.expectedFailure
def test_split(self,):
s = "hello world"
self.assertIn(
s.split(), [["hello", "world"]],
)
# ÕâÀïÔ¤¼ÆÅ׳öÒì³££¬µ«Êµ¼ÊûÓÐÒì³££¬±¾ÖÊÉÏÕâÒ²ËãÒ»ÖÖÒì³£
# ¿ÉÒÔʹÓÃ@unittest.expectedFailure
with self.assertRaises(TypeError):
s.split("ZMZ")
if __name__ == "__main__":
unittest.main()
ÔËÐÐÄãµÄ²âÊԽű¾:
# ½¨ÒéʹÓÃpytestÖ´ÐвâÊԽű¾£¬ÄãµÄpythonÖÐÍùÍù×Ô´øÕâ¸ö¹¤¾ß°ü
# ÕâʱÄã²»±ØÐ´ÏÂÖ÷º¯Êý£¬²¢ÇÒËûµÄÊä³öÐÎʽ¸üÃÀ¹Û
pytest test_myfile.py
Êä³öЧ¹û:
======================== test session starts =========================
platform linux -- Python 3.7.3, pytest-5.0.1, py-1.8.0, pluggy-0.12.0
rootdir: /root
plugins: remotedata-0.3.1, celery-4.3.0, doctestplus-0.3.0, arraydiff-0.3, openfiles-0.3.2
collected 3 items
test_myfile.py sx. [100%]
=========== 1 passed, 1 skipped, 1 xfailed in 0.34 seconds ===========
ÕæÊµµ¥Ôª²âÊԽű¾Çë²Î¿¼Pytorch TestsºÍTensorflow Tests
¹ý³Ì
ÔÚ×¼±¸³ÉΪ¹±Ï×Õß֮ǰ£¬ÒªÈ·±£ÄãÒѾÄܹ»ÊìÁ·Ê¹ÓøÃÏîÄ¿¡£½ø¶øÃ÷È·ÄãÒª¹±Ï×Ô´ÂëµÄÀàÐÍ£¬ÊÇFix Bug»¹ÊÇImplement New Feature(ʵÏÖÐÂÌØÐÔ)¡£µ±È»£¬¶ÔÒ»¸öÐÂÊÖ¹±Ï×ÕßÀ´½²£¬Fix BugÊÇÄãµÄ²»¶þÑ¡Ôñ¡£³ý·ÇÄãÒѾͨ¹ý×Ô¼ºµÄʵ¼ù£¬Ã÷È·ÁËÒª×ö¹±Ï׵ľßÌåÄÚÈÝ£¬·ñÔò£¬½¨ÒéÄãÐèÒª×ñÑÒÔϲ½Öè:
µÚÒ»²½£º
´Ó¿ªÔ´ÏîÄ¿µÄGithub IssuesÖÐѰÕÒopenµÄÎÊÌ⣬ÕâÀïÊÇTensorflow Issues, Pytorch Issues£¬×ÐϸÔĶÁ´ó¼ÒÌá³öµÄÎÊÌ⣬Õ⽫°ïÄãÔÚѰÕÒÎÊÌâÉϽÚÔ¼´óÁ¿Ê±¼ä£¬Í¬Ê±Äã¿ÉÒÔÔÚÌÖÂÛÇø¿´µ½Óйؼ¼ÊõµÄÌÖÂÛ»òÒѾÌá½»µÄPR£¬½øÒ»²½Ã÷È·×Ô¼ºÊÇ·ñÓ¦¸Ã²ÎÓë¸ÃÎÊÌâµÄ½â¾ö¡£(Óкܶ࿪ԴÏîÄ¿µÄissue»á´øÓÐ"contributions welcome"µÄ±êÇ©£¬¿ÉÒÔÓÅÏÈ¿´Ò»¿´¡£)
µÚ¶þ²½£º
µ±ÄãÃ÷È·ÁË×Ô¼ºÒª½â¾öµÄÎÊÌ⣬ÔÚÕýʽд´úÂë֮ǰ£¬ÄãÐèÒªforkÕâ¸ö¿ªÔ´ÏîÄ¿µ½Äã×Ô¼ºµÄGithub²Ö¿â£¬È»ºóÔÙ½«¸Ã²Ö¿âcloneµ½×Ô¼ºÖ¸¶¨µÄ·þÎñÆ÷ÉÏ£¬ÕâÑù×îºóÄã²Å¿ÉÒÔÌá½»PR¡£
# ÀýÈç:
git clone https://github.com/AITutorials/tensorflow.git
µ½ÕâÀïÄã¿ÉÒÔͨ¹ýgit remote -v·¢ÏÖÎÒÃÇÖ»Óë×Ô¼ºÔ¶³Ì²Ö¿â½øÐÐÁËÁ¬½Ó(origin/master)¡£
´ËʱÎÒÃÇ»¹ÐèÒªÓ뿪ԴÏîÄ¿µÄÔ¶³Ì²Ö¿â½¨Á¢Á¬½Ó(upstream/master)
# ÒÔtensorflowΪÀý½¨Á¢Á¬½Ó
git remote add upstream https://github.com/tensorflow/tensorflow.git
# ²é¿´µ½upstream
git remote -v
È»ºóÄã¾ÍÐèÒª½¨Á¢Ò»¸ö×Ô¼ºµÄ·ÖÖ§£¬µ±È»£¬Äã¿ÉÒÔÏȲ鿴һÏÂÔ¶³ÌµÄ·ÖÖ§Çé¿ö
# ²é¿´Ô¶³Ì·ÖÖ§
git branch -a
# ´´½¨×Ô¼ºµÄÔ¶³Ì·ÖÖ§cnsync
git checkout -b cnsync
µÚÈý²½£º
ͨ¹ýµÚ¶þ²½ÄãÒѾÄõ½ÁËÏîÄ¿µÄÔ´Âë²¢´´½¨ÁË×Ô¼º·ÖÖ§£¬Õâʱ¾ÍÒª¿ªÊ¼ÄãµÄ±íÑÝ£¬coding + review£¬Äã֮ǰ׼±¸µÄ´úÂë¹æ·¶¹¤¾ßºÍµ¥Ôª²âÊÔ¹¤¾ß½«ÅÉÉÏÓó¡¡£
µÚËIJ½£º
Ìá½»´úÂëÄãµÄ´úÂë²¢ÔÚgithubÖд´½¨Ò»¸öPR¡£
# °ÑÄÚÈÝÌí¼Óµ½ÔÝ´æÇø
git add .
# Ìá½»¸ü¸ÄµÄÄÚÈÝ
git commit -m "Ìí¼ÓÄãµÄ¸Ä±ä˵Ã÷"
# pushµ½×Ô¼ºµÄÔ¶³Ì²Ö¿â
git push origin cnsync
×¢Ò⣺ÕâÀïËäÈ»ÄãÖ»pushµ½ÁË×Ô¼ºµÄÔ¶³Ì²Ö¿â£¬µ«ÆäʵÄãµÄÔ¶³Ì²Ö¿âºÍÔ´ÏîÄ¿µÄ²Ö¿âÊÇÁ¬½ÓµÄ¡£Ò²¾ÍÊÇ˵£¬´ËʱÄã¿ÉÒÔͨ¹ý²Ù×÷×Ô¼ºµÄÔ¶³Ì²Ö¿â¾ö¶¨ÊÇ·ñ½«´´½¨Ò»¸öÔ´ÏîÄ¿µÄPR(ÕâЩ¹ý³Ì¿ÉÒÔÔÚÄã¸Õ¸ÕforkµÄÏîÄ¿Ò³ÃæÖÐʵÏÖ£¬°üÀ¨ÌîдPRµÄtitleºÍcomment£¬ÓÐʱÄãÒ²ÐèÒªÔÚtitleÖÐÌí¼ÓÒ»¸ö±ê¼Ç£¬Èç[Draft]/[WIP]/[RFR]µÈµÈ)¡£
µÚÎå²½:
ÄÍÐĵĵȴý£¬Èç¹ûÄãÊÇPRÊÇÒ»¸öReady For ReviewµÄ״̬£¬Ëü½«ºÜ¿ì½øÈë×Ô¶¯»¯²âÊÔµÄÁ÷³ÌÒÔ¼°ÆÀί»áµÄ½éÈ룬²»¾ÃºóÄ㽫ÊÕµ½Ò»Ð©·´À¡£¬ÄãµÄ´úÂë·½°¸¿ÉÄܱ»²ÉÄÉ£¬¿ÉÄÜÐèÒª¸ü¶àµÄÐ޸Ļò²âÊÔ¡£
½áÓï
×îÖÕ£¬¾¹ý²»¶ÏµØÄ¥Á·£¬Ä㽫³ÉΪһÃû½Ü³ö¿ªÔ´ÏîÄ¿µÄ¹±Ï×Õߣ¬ËùÒÔ£¬¼ÓÓͰÉÉÙÄê!
²ÂÄãϲ»¶£º
ÓïÑÔÄ£ÐÍ-BERT£ºbertËã·¨½éÉÜ
È˹¤ÖÇÄÜËã·¨ÈçºÎѧϰÊý¾ÝÖеĹæÂÉ?
ÇóTopNÈÈËѹؼü´Ê