Почему я получаю сообщение об ошибке: Тензор удаляется при использовании tf.grad () для реализации FGSM? - PullRequest
0 голосов
/ 14 марта 2019

Я пытаюсь реализовать метод быстрого градиентного знака (FGSM) в MobileNet с tenorflow.js, однако у меня возникают проблемы с последней версией (1.0.1) при вычислении градиента с помощью tf.grad ().

Код работает нормально с tfjs версии 0.13.0 и ниже, однако обновление до любой более поздней версии приводит к следующей ошибке:

core.js:15723 ERROR Error: Uncaught (in promise): Error: Tensor is disposed. Error: Tensor is disposed.
at e.throwIfDisposed (tf-core.esm.js:17)
at e.greaterEqual (tf-core.esm.js:17)
at Object.$x (tf-core.esm.js:17)
at n (tf-core.esm.js:17)
at backpropagateGradients (tf-core.esm.js:17)
at tf-core.esm.js:17
at tf-core.esm.js:17
at e.scopedRun (tf-core.esm.js:17)
at e.tidy (tf-core.esm.js:17)
at e.gradients (tf-core.esm.js:17)
at resolvePromise (zone.js:831)
at zone.js:896
at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:423)
at Object.onInvokeTask (core.js:17289)
at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:422)
at Zone.push../node_modules/zone.js/dist/zone.js.Zone.runTask (zone.js:195)
at drainMicroTaskQueue (zone.js:601)
at push../node_modules/zone.js/dist/zone.js.ZoneTask.invokeTask (zone.js:502)
at ZoneTask.invoke (zone.js:487)
at timer (zone.js:2281)

Ошибка возникает при вызове tf.grad(lossFunction):

Любая помощь / понимание приветствуется!

Полный код:

let canvas = <HTMLCanvasElement> document.getElementById('canvas')

let img = tf.browser.fromPixels(canvas, 3) //let img = tf.fromPixels(canvas, 3)
let img4 = tf.browser.fromPixels(canvas, 4) //let img4 = tf.fromPixels(canvas, 4)

let model = mobilenet.load().then(model =>
{
    var output = model.classify(img, 3).then(predictions =>
    {
        let tbuffer = tf.buffer([1000])
        var labelClasses = IMAGENET_CLASSES 

        let targetClass = predictions[0].className
        Object.keys(labelClasses).forEach(function(key) 
        {
            if (labelClasses[key].valueOf() == targetClass.valueOf()) 
            {
                tbuffer.set(1, parseInt(key));
            }
        })          

        const oneHotLabels = tbuffer.toTensor()

        const getModelLogits = x => model.infer(x)
        const lossFunction = x => tf.losses.softmaxCrossEntropy(oneHotLabels, getModelLogits(x).as1D())
        const gradientFunction = tf.grad(lossFunction)
        var gradient = gradientFunction(img)


        // scale the gradient and apply to original image
        var perturbation = this.scaleGradient(gradient, 50)
        const zeroes = new Uint8Array(224*224).fill(0)
        let alphaChannel = tf.tensor3d(zeroes, [224, 224, 1]) 
        let perturbationWithAlpha = tf.concat([perturbation, alphaChannel], 2)  
        var adversarialImage = tf.add(tf.cast(img4,'float32'), perturbationWithAlpha)

        // Draw adversarial image to canvas
        var context = canvas.getContext("2d")
        let imgArray = Uint8ClampedArray.from(adversarialImage.dataSync());
        let imgData = context.createImageData(this.imgHeight, this.imgWidth);
        imgData.data.set(imgArray);
        context.putImageData(imgData, 0, 0);            

    }) 
})  

Полное репо доступно здесь: https://github.com/BenMcFadyen/tfjsFGSM https://github.com/BenMcFadyen/tfjsFGSM/blob/master/src/app/app.component.ts

FGSM-код от: https://github.com/jaxball/advis.js

полный след

успешное выполнение

Ответы [ 2 ]

2 голосов
/ 19 марта 2019

tensorflow-models/mobilenet@0.2.2 был tf.LayersModel, который обеспечивает градиенты и, следовательно, может быть переобучен. Однако tenensflow-models/mobilenet@1.0.0 был изменен на tf.GraphModel в https://github.com/tensorflow/tfjs-models/pull/161,, чтобы обеспечить MobileNet V2 от TF-Hub. GraphModels не предоставляют градиенты, и поэтому ваш код больше не работает.

Я думаю, у вас есть несколько возможных путей продвижения вперед:

  1. Придерживайтесь рабочих версий, если они удовлетворяют вашим потребностям (tenensflow-models/mobilenet@0.2.2 должен работать с tfjs до 0.15.3, хотя это приведет к предупреждению об устаревании).
  2. Создайте файл tenorflow / tfjs-models в PR # 156 и соберите там пакет mobilenet. Это то же самое, что и 0.2.2, за исключением того, что его можно использовать с tfjs> 1.0.0.
  3. Создайте тензор потока / tfjs-models из головы и верните часть загрузки модели, чтобы использовать tf.loadLayersModel() с BASE_PATH, который был удален в # 161. (Это дает вам только V1).
  4. Получите MobileNet V2 в формате Keras .h5 (например, с здесь ) и используйте конвертер TF.js , чтобы получить tf.LayersModel.
1 голос
/ 19 марта 2019

Я воспроизвел ошибку и вручную проверил, что https://github.com/tensorflow/tfjs-core/pull/1604 исправляет ее. Исправление будет выпущено в следующем выпуске TF.js (1.0.2), который мы планируем выпустить к концу этой недели.

Градиенты работают даже при том, что MobileNet теперь tf.GraphModel вместо tf.LayersModel, потому что библиотека стремится и может вычислять градиенты на лету.

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