Массив Numpy: функция также влияет на исходный объект ввода - PullRequest
1 голос
/ 21 апреля 2019

Я работаю над своей персональной функцией увеличения изображения в TensorFlow 2.0 . Более конкретно, я написал функцию, которая возвращает случайно увеличенное изображение. Его вход image_batch, многомерный массив numpy с формой:

(no. images, height, width, channel)

, что в моем конкретном случае:

(31, 300, 300, 3)

Это код:

def random_zoom(batch, zoom=0.6):
    '''
    Performs random zoom of a batch of images.
    It starts by zero padding the images one by one, then randomly selects
     a subsample of the padded image of the same size of the original.
    The result is a random zoom
    '''

    # Import from TensorFlow 2.0
    from tensorflow.image import resize_with_pad, random_crop

    # save original image height and width
    height = batch.shape[1]
    width = batch.shape[2]

    # Iterate over every image in the batch
    for i in range(len(batch)):
        # zero pad the image, adding 25-percent to each side
        image_distortion = resize_with_pad(batch[i, :,:,:], int(height*(1+zoom)), int(width*(1+zoom)))

        # take a subset of the image randomly
        image_distortion = random_crop(image_distortion, size=[height, width, 3], seed = 1+i*2)

        # put the distorted image back in the batch
        batch[i, :,:,:] = image_distortion.numpy()

    return batch

Затем я могу вызвать функцию:

new_batch = random_zoom(image_batch)

В этот момент происходит нечто странное: new_batch изображений - это то, что я и ожидал, и я доволен этим ... но теперь также image_batch, исходный объект ввода, был изменен! Я не хочу этого, и я не понимаю, почему это происходит.

1 Ответ

2 голосов
/ 21 апреля 2019

Ну, эта строка batch[i, :,:,:] = image_distortion.numpy() изменяет массив, который передается в качестве аргумента.

Ваша путаница, вероятно, связана с знакомством с другим языком, таким как C ++, где объекты, переданные в качестве аргументов, неявно копируются.

В Python происходит то, что вы можете назвать передачей по ссылке.Копии не делаются, если вы не хотите, чтобы они были .Следовательно, это не значит, что и new_batch, и image_batch изменены;это два имени, указывающие на один и тот же объект, который был изменен.

Соответственно, вы можете захотеть сделать что-то вроде batch = batch.copy() в начале вашей функции.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...