0

I know that a variable assignment in python is not the same as in C or C++. This post shows how multiply variable are created at once. However, they all point to the same object. Today I've studies some GitHub Code and came across this:

    in_x = x = Input((2, 6, 7))  # [own(8x8), enemy(8x8)]

    # (batch, channels, height, width)
    x = Conv2D(filters=mc.cnn_filter_num, kernel_size=mc.cnn_filter_size, padding="same",
               data_format="channels_first", kernel_regularizer=l2(mc.l2_reg))(x)
    x = BatchNormalization(axis=1)(x)
    x = Activation("relu")(x)

    for _ in range(mc.res_layer_num):
        x = self._build_residual_block(x)

    res_out = x
    # for policy output
    x = Conv2D(filters=2, kernel_size=1, data_format="channels_first", kernel_regularizer=l2(mc.l2_reg))(res_out)
    x = BatchNormalization(axis=1)(x)
    x = Activation("relu")(x)
    x = Flatten()(x)
    # no output for 'pass'
    policy_out = Dense(self.config.n_labels, kernel_regularizer=l2(mc.l2_reg), activation="softmax", name="policy_out")(x)

    # for value output
    x = Conv2D(filters=1, kernel_size=1, data_format="channels_first", kernel_regularizer=l2(mc.l2_reg))(res_out)
    x = BatchNormalization(axis=1)(x)
    x = Activation("relu")(x)
    x = Flatten()(x)
    x = Dense(mc.value_fc_size, kernel_regularizer=l2(mc.l2_reg), activation="relu")(x)
    value_out = Dense(1, kernel_regularizer=l2(mc.l2_reg), activation="tanh", name="value_out")(x)

It's a Keras model for a deep learning problem. The context doesn't matter. Roughly it works as follows. The input x is passed trough two branches with CNN Layers. Therefor there will be two losses in the end. Now to the actual question.

In the middle the author creates the variable res_out and assigns x to it. This should be the branch (as far as I understand it). He continues to work with x. At "# for value output" he starts the branch working with res_out. Obviously it is assumed that res_out is a copy of that old x at the branching point. Otherwise there is not really a need for this variable.

But isn't res_out pointing to the same object as x? This would mean that there is actually know branch, just an additional CNN block. Are there different assignments in python which are sometimes deep and sometimes shallow copies?

Mr.Sh4nnon
  • 327
  • 2
  • 20
  • 1
    Your first paragraph is just not true, that does not happen. – Daniel Roseman Dec 11 '18 at 21:02
  • 1
    But nevertheless, this is bad code. There's no reason to keep reassigning to x; the author should use different variables, or do the operations inline. – Daniel Roseman Dec 11 '18 at 21:03
  • @DanielRoseman ou okay. But whats this post referring to? https://stackoverflow.com/questions/2438938/python-copy-through-assignment why are some variables copied and others share an object? – Mr.Sh4nnon Dec 11 '18 at 21:05
  • 1
    In that question, the dict was not reassigned, it was mutated. – Daniel Roseman Dec 11 '18 at 21:37
  • Well, so not that much difference to C, except no types.... How do I know that e.g. numpy arrays have to be copied otherwise they are just referred, and e.g. integer variables are copied? – Mr.Sh4nnon Dec 11 '18 at 21:42
  • That's not at all what I said the difference was. It is not a difference of types, but of actions. In that question, the contents of a dict is being changed; the dict itself is not being reassigned. In your example, you are reassigning a variable to a completely different object. (It so happens that talking about "mutating" the contents of an integer makes no sense, so that action does not apply; but if in the linked question the code was `dictc = {'hello': 'goodbye'}`, that would also be a reassignment and the other two dicts would be *unaffected*.) – Daniel Roseman Dec 11 '18 at 21:54
  • See https://nedbatchelder.com/text/names.html for a better explanation, but also note that the exact same semantics apply in Ruby, JavaScript and Java, among other languages. – Daniel Roseman Dec 11 '18 at 21:55

0 Answers0