您好,登錄后才能下訂單哦!
本篇文章為大家展示了如何正確的使用tensorflow __init__、build 和call,內容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。
class RB(tf.keras.layers.Layer): def __init__(self, num_filters, *args, **kwargs): self.num_filters = num_filters super(RB, self).__init__(*args, **kwargs) #按需求添加卷積 def build(self, input_shape): #按需求添加卷積 self._layers = [ ] super(RB, self).build(input_shape) def call(self, tensor): for layer in self._layers: tensor = layer(tensor) class DecodeNet(tf.keras.layers.Layer): def __init__(self, num_filters, *args, **kwargs): self.num_filters = num_filters super(DecodeNet, self).__init__(*args, **kwargs) self.rb_block0 = RB(self.num_filters) self.rb_block1 = RB(self.num_filters) self.rb_block2 = RB(self.num_filters) def build(self, input_shape): self._layers = [ RB(self.num_filters), RB(self.num_filters), RB(self.num_filters), ] super(DecodeNet, self).build(input_shape) def call(self, tensor): tensor = self.rb_block0(tensor) tensor = self.rb_block1(tensor) for layer in self._layers: tensor = layer(tensor) tensor = self.rb_block2(tensor) return tensor
補充:Python類中的__init__() 和 self 的解析
self,英文單詞意思很明顯,表示自己,本身。
此處有幾種潛在含義:
1.這里的自己,指的是,實例Instance本身。
2.同時, 由于說到“自己”這個詞,都是和相對而言的“其他”而說的;而此處的其他,指的是,類Class,和其他變量,比如局部變量,全局變量等。
此處的self,是個對象(Object),是當前類的實例。
因此,對應的self.valueName 和 self.function()中的valueName:表示self對象,即實例的變量。與其他的,Class的變量,全局的變量,局部的變量,是相對應的。
function:表示是調用的是self對象,即實例的函數。與其他的全局的函數,是相對應的。
那就是:
在類的代碼(函數)中,需要訪問當前的實例中的變量和函數的,即,訪問Instance中的:
對應的變量(屬性,property):Instance.ProperyNam,去讀取之前的值和寫入新的值
調用對應函數(function):Instance.function(),即執行對應的動作
-> 而需要訪問實例的變量和調用實例的函數,當然需要對應的實例Instance對象本身
-> 而Python中就規定好了,函數的第一個參數,就必須是實例對象本身,并且建議,約定俗成,把其名字寫為self
-> 所以,我們需要self(需要用到self)
而如果沒有用到self,即代碼中,去掉self后,那種寫法所使用到的變量,實際上不是你所希望的,不是真正的實例中的變量和函數,而是的訪問到了其他部分的變量和函數了。甚至會由于沒有合適的初始化實例變量,而導致后續無法訪問的錯誤。
下面,就通過代碼,來演示,如果去掉self,或者沒有合理的使用self,會出現哪些錯誤。
#!/usr/bin/env python # -*- coding:utf-8 -*- # Author: antcolonies class Person(object): def __init__(self, name, lang, website): self.name = name self.lang = lang self.website = website print('self: ', self) print('type of self: ', type(self)) ''' 未實例化時,運行程序,構造方法沒有運行 ''' p = Person('Tim', 'English', 'www.universal.com') '''實例化后運行的結果 self: <__main__.Person object at 0x00000000021EAF98> type of self: <class '__main__.Person'> '''
可以看出self為實例變量p,是一個Person類型的對象。
class Dog(object): def __init__(self,name,dog_type): self.name = name self.type = dog_type def sayhi(self): print("hello,I am a dog, my name is ",self.name) d = Dog('LiChuang',"京巴") # 實例化 d.sayhi()
以下是d = Dog('LiChuang',"京巴")實例化的示意圖:
如下代碼,完整的演示了,如果沒有在類Class的最初的__init__函數中,正確的初始化實例變量,則會導致后續沒有變量可用,因而出現AttributeError的錯誤:
#!/usr/bin/env python # -*- coding:utf-8 -*- # Author: antcolonies name = 'whole global name' ''' 注:此處全局的變量名,寫成name,只是為了演示而用 實際上,好的編程風格,應該寫成gName之類的名字, 以表示該變量是Global的變量 ''' class Person(object): def __init__(self, newPersonName): # self.name = newPersonName ''' 如果此處不寫成self.name 那么此處的name,只是__init__函數中的局部臨時變量name而已 和全局中的name,沒有半毛錢關系 ''' name = newPersonName ''' 此處只是為了代碼演示,而使用了局部變量name, 不過需要注意的是,此處很明顯,由于接下來的代碼也沒有利用到此處的局部變量name 則就導致了,此處的name變量,實際上被浪費了,根本沒有利用到 ''' def sayYourName(self): ''' 此處由于找不到實例中的name變量,所以會報錯: AttributeError: Person instance has no attribute 'name' ''' print('My name is %s' %self.name) def selfAndInitDemo(): personInstance = Person('Tim') personInstance.sayYourName() if __name__ == '__main__': selfAndInitDemo() ''' 未使用self.name時拋異常 Traceback (most recent call last): File "E:/python14_workspace/s14/day06/test_1.py", line 18, in <module> selfAndInitDemo() File "E:/python14_workspace/s14/day06/test_1.py", line 15, in selfAndInitDemo personInstance.sayYourName() File "E:/python14_workspace/s14/day06/test_1.py", line 11, in sayYourName print('My name is %s' %self.name) AttributeError: 'Person' object has no attribute 'name' '''
從上述代碼可見,由于在類的初始化(實例化)的__init__函數中,沒有給self.name設置值,使得實例中,根本沒有name這個變量,導致后續再去訪問self.name,就會出現AttributeError的錯誤了。
對應的,如果寫成self.name,則意思就正確了,就是初始化的時候,給實例中新增加,并且正常設置了正確的值newPersionName了,所以后續再去通過self.name,就可以訪問到,當前實例中正確的變量name了。
相應的正確寫法的代碼如下:
#!/usr/bin/env python # -*- coding:utf-8 -*- # Author: antcolonies name = 'whole global name' ''' 注:此處全局的變量名,寫成name,只是為了演示而用 實際上,好的編程風格,應該寫成gName之類的名字, 以表示該變量是Global的變量 ''' class Person(object): def __init__(self, newPersonName): self.name = newPersonName ''' 此處正確的,通過訪問self.name的形式,實現了: 1.給實例中,增加了name變量 2.并且給name賦了初值,為newPersionName ''' def sayYourName(self): ''' 此處由于開始正確的初始化了self對象,使得其中有了name變量, 所以此處可以正確訪問了name值了 ''' print('My name is %s' %self.name) def selfAndInitDemo(): personInstance = Person('Tim') personInstance.sayYourName() if __name__ == '__main__': selfAndInitDemo() '''My name is Tim'''
雖然代碼是可以運行的,但是實際上卻是使用的,不是實例中的變量
有時候,雖然你寫的代碼,可以運行,但是使用到的變量,由于沒有加self,實際上是用到的不是實例的變量,而是其他的變量。
此類問題,主要和Python中的變量的作用域有關,但是此處例子中,也和是否使用self有關:
#!/usr/bin/env python # -*- coding:utf-8 -*- # Author: antcolonies name = 'whole global name' ''' 注:此處全局的變量名,寫成name,只是為了演示而用 實際上,好的編程風格,應該寫成gName之類的名字, 以表示該變量是Global的變量 ''' class Person(object): name = 'class global name' def __init__(self, newPersonName): # self.name = newPersonName ''' 此處,沒有使用self.name 而使得此處的name,實際上仍是局部變量name 雖然此處賦值了,但是后面沒有被利用到,屬于被浪費了的局部變量name ''' name = newPersonName def sayYourName(self): ''' 此處,之所以沒有像之前一樣出現: AttributeError: Person instance has no attribute 'name' 那是因為,雖然當前的實例self中,沒有在__init__中初始化對應的name變量,實例self中沒有對應的name變量 但是由于實例所對應的類Person,有對應的name變量,所以也是可以正常執行代碼的 對應的,此處的self.name,實際上是Person.name ''' print('My name is %s' %self.name) print('Name within class Person is actually the global name: %s' %name) print("Only access Person's name via Person.name = %s" %(Person.name)) def selfAndInitDemo(): personInstance = Person('Tim') personInstance.sayYourName() print('whole global name is %s' %name) if __name__ == '__main__': selfAndInitDemo() ''' My name is class global name Name within class Person is actually the global name: whole global name Only access Person's name via Person.name = class global name whole global name is whole global name '''
其中,可見,此處開始__init__中,沒有給self實例初始化對應的name,
而后面的函數sayYourName中,雖然可以調用到self.name而沒有出現AttributeError錯誤,
但是實際上此處的值,不是所期望的,傳入的name,即"Tim",而是類中的name的值,即"class global name"。
上述內容就是如何正確的使用tensorflow __init__、build 和call,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。