我觀察到這些TensorFlow方法喜歡assign_add并assign_sub修改物件和類(如果存在)的變數。這是一個簡單的代碼來重現我的觀察。任何人都可以澄清這種行為(assign_sub并assign_add修改類和實體屬性)嗎?
#a python class
class myc_base():
a=1.
def __init__(self, b=1.):
self.b=b
def add(self, to_add=1.):
self.a =to_add
self.b =to_add
def sub(self, to_sub=1.):
self.a-=to_sub
self.b-=to_sub
obj_base=myc_base()
print(f'Init. -- class.a: {myc_base.a} | obj.a: {obj_base.a}, obj.b: {obj_base.b}')
obj_base.add(5.)
print(f'after add -- class.a: {myc_base.a} | obj.a: {obj_base.a}, obj.b: {obj_base.b}')
obj_base.sub(2.)
print(f'after sub -- class.a: {myc_base.a} | obj.a: {obj_base.a}, obj.b: {obj_base.b}')
輸出:
Init. -- class.a: 1.0 | obj.a: 1.0, obj.b: 1.0
after add -- class.a: 1.0 | obj.a: 6.0, obj.b: 6.0
after sub -- class.a: 1.0 | obj.a: 4.0, obj.b: 4.0
使用張量流:
import tensorflow as tf
#a class for tf operations
class myc_tf():
a=tf.Variable(1.)
def __init__(self, b=tf.Variable(1.)):
self.b=b
def add(self, to_add=1.):
self.a.assign_add(to_add)
self.b.assign_add(to_add)
def sub(self, to_sub=1.):
self.a.assign_sub(to_sub)
self.b.assign_sub(to_sub)
obj_tf=myc_tf()
print(f'Init. -- class.a: {myc_tf.a.numpy()} | obj.a: {obj_tf.a.numpy()}, obj.b: {obj_tf.b.numpy()}')
obj_tf.add(5.)
print(f'after add -- class.a: {myc_tf.a.numpy()} | obj.a: {obj_tf.a.numpy()}, obj.b: {obj_tf.b.numpy()}')
obj_tf.sub(2.)
print(f'after sub -- class.a: {myc_tf.a.numpy()} | obj.a: {obj_tf.a.numpy()}, obj.b: {obj_tf.b.numpy()}')
輸出:
Init. -- class.a: 1.0 | obj.a: 1.0, obj.b: 1.0
after add -- class.a: 6.0 | obj.a: 6.0, obj.b: 6.0
after sub -- class.a: 4.0 | obj.a: 4.0, obj.b: 4.0
uj5u.com熱心網友回復:
a是類屬性。b是一個實體屬性。
然而,增強任務如
self.a = to_add
self.a -= to_sub
沒有修改您認為您正在通過實體訪問的類屬性。它們實際上等同于
self.a = self.a.__iadd__(to_add)
self.a = self.a.__isub__(to_sub)
所以第一次使用時,會在 RHS 上訪問類屬性,但隨后會創建一個新的實體屬性,并且該實體屬性會在以后的所有呼叫中隱藏類屬性。
如果要通過實體修改類屬性,則需要明確說明。一種可能的解決方案:
type(self).a = to_add
您的 TensorFlow 代碼不會進行任何賦值,無論是擴充的還是其他方式。它只是對任何self.a決議為類屬性的方法呼叫。從未創建新的實體屬性。
uj5u.com熱心網友回復:
當類使用您創建的變數和 init() 函式啟動時,您需要了解類和區域變數。assign_add() 和 assign_sub() 已更新并等待值更新,但 python 類將在釋放或重新分配值后擦除。
示例:var1 和 var2 都從 10 開始,var2 以 100 作為在類及其函式中使用的區域變數。通過 var1 為它分配了 more 30 作為區域變數。更新可以到達 var1 為 40,var2 為 10,因為 var2 從不在函式之外,結果為 100。
import os
from os.path import exists
import tensorflow as tf
import matplotlib.pyplot as plt
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""
: Class and Functions
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""
class MyDenseLayer(tf.keras.layers.Layer):
var1 = tf.Variable([10.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0])
var2 = tf.Variable([10.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0])
def __init__(self, num_outputs):
super(MyDenseLayer, self).__init__()
self.num_outputs = num_outputs
self.var2 = self.var1 * 10.0
def build(self, input_shape):
self.kernel = self.add_weight("kernel",
shape=[int(input_shape[-1]),
self.num_outputs])
def call(self, inputs):
self.var1.assign_add([30.0, 30.0, 30.0, 30.0, 30.0, 30.0, 30.0, 30.0, 30.0, 30.0])
temp = tf.constant( self.var2 ).numpy()
return temp
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""
: Variables
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""
start = 3
limit = 33
delta = 3
# Create DATA
sample = tf.range(start, limit, delta)
sample = tf.cast( sample, dtype=tf.float32 )
# Initail, ( 10, 1 )
sample = tf.constant( sample, shape=( 10, 1 ) )
layer = MyDenseLayer(10)
data = layer(sample)
print( tf.constant( MyDenseLayer.var1 ).numpy() )
print( tf.constant( MyDenseLayer.var2 ).numpy() )
print( data )
輸出:本地 var1、本地 var2(無賦值函式)和資料(類更新的結果)
[40. 40. 40. 40. 40. 40. 40. 40. 40. 40.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[100. 100. 100. 100. 100. 100. 100. 100. 100. 100.]
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/537859.html
