Executing model on react-native-pytorch-core not working

username: rqasmi
cooked: <p>I am working on a react-native project that was bootstrapped through expo-cli. It is a very basic app that only has a camera feature for now. I have my own trained PyTorch model on some dataset and my goal is to test the model on-device through the app. I followed the steps <a href="https://pytorch.org/live/docs/tutorials/add-package/" rel="noopener nofollow ugc">here</a>  to add the <code>react-native-pytorch-core</code> library and also implemented these steps <a href="https://pytorch.org/live/docs/tutorials/prepare-custom-model/" rel="noopener nofollow ugc">https://pytorch.org/live/docs/tutorials/prepare-custom-model/</a> to bundle the model with the app. However, when trying to run the model on the captured photo imported, I am always getting <code>null is not an object</code>. I have my model under <code>assets/models</code> which should bundle with the app. I guess I am missing something but I couldn’t figure it out since the documentation is scarce. I have attached the code below and a screenshot of the stacktrace.</p>
<p>This is the TakePhoto component:</p>
<pre><code class="lang-auto">import { StatusBar } from 'expo-status-bar';
import { SafeAreaProvider } from 'react-native-safe-area-context';
import { Camera } from 'expo-camera';
import React, { useState, useEffect, useRef } from 'react';
import { Text, View, TouchableOpacity, StyleSheet, Image, Dimensions, Button } from 'react-native';
import { MobileModel, ModelResult, Image as img, ImageUtil } from 'react-native-pytorch-core';

const model = require('../assets/models/model_best_resnet.ptl');

type ImageClassificationResult = {
  maxIdx: number;
  confidence: number;
};

export default function TakePhoto(props) {
  const [hasPermission, setHasPermission] = useState(null);
  const [cameraRef, setCameraRef] = useState(null);
  const [type, setType] = useState(Camera.Constants.Type.back);
  const [photo, setPhoto] = useState(null);

  useEffect(() =&gt; {
      (async () =&gt; {
        const { status } = await Camera.requestCameraPermissionsAsync();
        setHasPermission(status === 'granted');
      })();
    }, []);

  async function classifyImage() {
    try {
      const {metrics, result} = await MobileModel.execute&lt;ImageClassificationResult&gt;(model, {photo,});
      console.log(metrics);
      console.log(result.confidence);
    } catch(exception) {
      console.log(exception);
    }
    
  }

  if (hasPermission === null) {
      return &lt;View /&gt;;
    }
    if (hasPermission === false) {
      return &lt;Text&gt;No access to camera&lt;/Text&gt;;
    }
    return (
      &lt;View style={{ flex: 1 }}&gt;
        { (photo == null) ?
        &lt;Camera style={{ flex: 1 }} type={type} ref={ref =&gt; {
          setCameraRef(ref);
        }}&gt;
          &lt;View
            style={styles.pictureView}&gt;
            &lt;TouchableOpacity
              style={styles.textCommand}
              onPress={() =&gt; {
                setType(
                  type === Camera.Constants.Type.back
                    ? Camera.Constants.Type.front
                    : Camera.Constants.Type.back
                );
              }}&gt;
              &lt;Text style={{ fontSize: 18, marginBottom: 10, color: 'white' }}&gt; Flip &lt;/Text&gt;
            &lt;/TouchableOpacity&gt;
            &lt;TouchableOpacity style={styles.textCommand} onPress={props.goBackHandler}&gt;
              &lt;Text style={{ fontSize: 18, marginBottom: 10, color: 'white' }}&gt; Close &lt;/Text&gt;
            &lt;/TouchableOpacity&gt;
            &lt;TouchableOpacity style={{alignSelf: 'center'}} onPress={async() =&gt; {
              if(cameraRef){
                let p = await cameraRef.takePictureAsync();
                setPhoto(p);
              }
            }}&gt;
              &lt;View style={styles.snapButtonOut}&gt;
                &lt;View style={styles.snapButtonIn} &gt;
                &lt;/View&gt;
              &lt;/View&gt;
            &lt;/TouchableOpacity&gt;
          &lt;/View&gt;
        &lt;/Camera&gt;
        : null }
        {
          (photo != null) ?
          &lt;View style={styles.photo}&gt;
            &lt;Image style={{flex:1, width: '100%', height: '100%'}} resizeMode={'contain'} source={photo}&gt;&lt;/Image&gt;
            &lt;Button onPress={() =&gt; setPhoto(null)} title="Retake"&gt;&lt;/Button&gt;
            &lt;Button onPress={classifyImage} title="Submit"&gt;&lt;/Button&gt;
          &lt;/View&gt; : null
        }
      &lt;/View&gt;
    );
  }
  const styles = StyleSheet.create({
    textCommand: {
      alignSelf: 'flex-end'
    },
    pictureView: {
      flex: 1,
      backgroundColor: 'transparent',
      justifyContent: 'flex-end'
    },
    snapButtonOut: {
        marginBottom: 20,
        borderWidth: 2,
        borderRadius:50,
        borderColor: 'white',
        height: 50,
        width:50,
        display: 'flex',
        justifyContent: 'center',
        alignItems: 'center'
    },
    snapButtonIn: {
      borderWidth: 2,
      borderRadius:50,
      borderColor: 'white',
      height: 40,
      width:40,
      backgroundColor: 'white'
  },
  photo: {
    flex: 1,
    borderRadius: 50,
  }
  });
</code></pre>
<p><div class="lightbox-wrapper"><a class="lightbox" href="https://discuss.pytorch.org/uploads/default/original/3X/0/4/049266426b12690b8470c4e8bb3c709563e4d6b5.png" data-download-href="https://discuss.pytorch.org/uploads/default/049266426b12690b8470c4e8bb3c709563e4d6b5" title="image"><img src="https://discuss.pytorch.org/uploads/default/original/3X/0/4/049266426b12690b8470c4e8bb3c709563e4d6b5.png" alt="image" data-base62-sha1="ErziekN1J6LSDV9Pwukj0FV1tz" width="586" height="499" data-dominant-color="2C303A"><div class="meta"><svg class="fa d-icon d-icon-far-image svg-icon" aria-hidden="true"><use href="#far-image"></use></svg><span class="filename">image</span><span class="informations">1094×932 50.5 KB</span><svg class="fa d-icon d-icon-discourse-expand svg-icon" aria-hidden="true"><use href="#discourse-expand"></use></svg></div></a></div></p>