Git Product home page Git Product logo

Comments (5)

firem-4 avatar firem-4 commented on May 21, 2024

same problem did you fix it ?

from nsfwjs-mobile.

minhchienwikipedia avatar minhchienwikipedia commented on May 21, 2024

Same issue

from nsfwjs-mobile.

shamshirsalams avatar shamshirsalams commented on May 21, 2024

Any update?

from nsfwjs-mobile.

FranciscoOssian avatar FranciscoOssian commented on May 21, 2024

I finally created a project with expo that integrates TensorFlow and this model. However, I encountered issues with the nsfw.js library (which is related to GIFs and has many web references) and had to modify it to work minimally with JPEGs. Despite these efforts, the model's predictions were incorrect or unexpected. I may have made an error when adapting methods from the library.

  "dependencies": {
    "@react-native-async-storage/async-storage": "^1.17.11",
    "@tensorflow/tfjs": "4.1.0",
    "@tensorflow/tfjs-react-native": "^0.8.0",
    "expo": "~47.0.12",
    "expo-camera": "~13.1.0",
    "expo-gl": "~12.0.1",
    "expo-image-manipulator": "~11.0.0",
    "expo-image-picker": "~14.0.2",
    "expo-splash-screen": "~0.17.5",
    "expo-status-bar": "~1.4.2",
    "jpeg-js": "^0.4.4",
    "nsfwjs": "^2.4.2",
    "react": "18.1.0",
    "react-native": "0.70.5",
    "react-native-fs": "^2.20.0"
  },
import React, { useState, useEffect } from "react";
import { View, Text, Image, Button } from "react-native";
import * as tf from "@tensorflow/tfjs";
import { bundleResourceIO } from "@tensorflow/tfjs-react-native";
import * as ImagePicker from "expo-image-picker";
import { decode as atob } from "base-64";
import * as jpeg from "jpeg-js";
import { manipulateAsync } from "expo-image-manipulator";
import { classify } from "./src/nsfw";

const modelJson = require("./assets/nsfw-model.json");
const modelWeights = require("./assets/nsfw-weights.bin");

const picInputShapeSize = {
  width: 224,
  height: 224,
};

function imageToTensor(rawImageData) {
  const TO_UINT8ARRAY = true;
  const { width, height, data } = jpeg.decode(rawImageData, TO_UINT8ARRAY);
  // Drop the alpha channel info for mobilenet
  const buffer = new Uint8Array(width * height * 3);
  let offset = 0; // offset into original data
  for (let i = 0; i < buffer.length; i += 3) {
    buffer[i] = data[offset];
    buffer[i + 1] = data[offset + 1];
    buffer[i + 2] = data[offset + 2];

    offset += 4;
  }

  return tf.tensor4d(buffer, [1, height, width, 3]);
}

const App = () => {
  const [model, setModel] = useState(null);
  const [predictions, setPredictions] = useState(null);
  const [image, setImage] = useState();

  useEffect(() => {
    const loadModel = async () => {
      // Carregando modelo
      await tf.ready();
      let model;
      try {
        model = await tf.loadLayersModel(
          bundleResourceIO(modelJson, modelWeights)
        );
      } catch (e) {
        console.log(e);
      }

      setModel(model);
    };
    loadModel();
  }, []);

  const classifyImage = async (uri) => {
    if (!uri) return;
    try {
      const resizedPhoto = await manipulateAsync(
        uri,
        [
          {
            resize: {
              width: picInputShapeSize.width,
              height: picInputShapeSize.height,
            },
          },
        ],
        { format: "jpeg", base64: true }
      );
      const base64 = resizedPhoto.base64;
      const arrayBuffer = Uint8Array.from(atob(base64), (c) => c.charCodeAt(0));
      const imageData = arrayBuffer;
      const imageTensor = imageToTensor(imageData); //decodeJpeg(imageData);
      const p = await classify(model, imageTensor);
      //setPredictions(p[0]);
      console.log(p);
    } catch (e) {
      console.log(e);
    }
  };

  const onHandlePick = async () => {
    let result = await ImagePicker.launchImageLibraryAsync({
      mediaTypes: ImagePicker.MediaTypeOptions.All,
      allowsEditing: true,
      quality: 1,
    });

    if (!result.canceled) {
      setImage(result.assets[0].uri);
    }
  };

  return (
    <View>
      <Image
        source={{ uri: image }}
        style={{ width: 200, height: 200 }}
        onLoad={() => classifyImage(image)}
      />
      <Button title="pick and predict" onPress={onHandlePick} />
      {predictions &&
        predictions.map((prediction, index) => (
          <Text key={index}>{prediction}</Text>
        ))}
    </View>
  );
};

export default App;
const NSFW_CLASSES = {
  0: "Drawing",
  1: "Hentai",
  2: "Neutral",
  3: "Porn",
  4: "Sexy",
};

export async function getTopKClasses(logits, topK) {
  const values = await logits.data();

  const valuesAndIndices = [];
  for (let i = 0; i < values.length; i++) {
    valuesAndIndices.push({ value: values[i], index: i });
  }
  valuesAndIndices.sort((a, b) => {
    return b.value - a.value;
  });
  const topkValues = new Float32Array(topK);
  const topkIndices = new Int32Array(topK);
  for (let i = 0; i < topK; i++) {
    topkValues[i] = valuesAndIndices[i].value;
    topkIndices[i] = valuesAndIndices[i].index;
  }

  const topClassesAndProbs = [];
  for (let i = 0; i < topkIndices.length; i++) {
    topClassesAndProbs.push({
      className: NSFW_CLASSES[topkIndices[i]],
      probability: topkValues[i],
    });
  }
  return topClassesAndProbs;
}

export const classify = async (model, img, topk = 5) => {
  const logits = model.predict(img);
  const classes = await getTopKClasses(logits, topk);
  logits.dispose();
  return classes;
};

this is the predict response when I teste with 1000000%%% nsfw image

[{"className": "Drawing", "probability": 0.5907529592514038}, {"className": "Hentai", "probability": 0.223214790225029}, {"className": "Neutral", "probability": 0.12099546194076538}, {"className": "Porn", "probability": 0.055417921394109726}, {"className": "Sexy", "probability": 0.009618803858757019}]

I currently had to downgrade tfjs-core, follow the explanation. (the current version is 4.2.0 and I moved to 4.1.0

tensorflow/tfjs#7273

edit: I can't confirm but I was also having a problem with tensorflow and using yarn resolve. But I could be wrong.

from nsfwjs-mobile.

net777infamous avatar net777infamous commented on May 21, 2024

I finally created a project with expo that integrates TensorFlow and this model. However, I encountered issues with the nsfw.js library (which is related to GIFs and has many web references) and had to modify it to work minimally with JPEGs. Despite these efforts, the model's predictions were incorrect or unexpected. I may have made an error when adapting methods from the library.

  "dependencies": {
    "@react-native-async-storage/async-storage": "^1.17.11",
    "@tensorflow/tfjs": "4.1.0",
    "@tensorflow/tfjs-react-native": "^0.8.0",
    "expo": "~47.0.12",
    "expo-camera": "~13.1.0",
    "expo-gl": "~12.0.1",
    "expo-image-manipulator": "~11.0.0",
    "expo-image-picker": "~14.0.2",
    "expo-splash-screen": "~0.17.5",
    "expo-status-bar": "~1.4.2",
    "jpeg-js": "^0.4.4",
    "nsfwjs": "^2.4.2",
    "react": "18.1.0",
    "react-native": "0.70.5",
    "react-native-fs": "^2.20.0"
  },
import React, { useState, useEffect } from "react";
import { View, Text, Image, Button } from "react-native";
import * as tf from "@tensorflow/tfjs";
import { bundleResourceIO } from "@tensorflow/tfjs-react-native";
import * as ImagePicker from "expo-image-picker";
import { decode as atob } from "base-64";
import * as jpeg from "jpeg-js";
import { manipulateAsync } from "expo-image-manipulator";
import { classify } from "./src/nsfw";

const modelJson = require("./assets/nsfw-model.json");
const modelWeights = require("./assets/nsfw-weights.bin");

const picInputShapeSize = {
  width: 224,
  height: 224,
};

function imageToTensor(rawImageData) {
  const TO_UINT8ARRAY = true;
  const { width, height, data } = jpeg.decode(rawImageData, TO_UINT8ARRAY);
  // Drop the alpha channel info for mobilenet
  const buffer = new Uint8Array(width * height * 3);
  let offset = 0; // offset into original data
  for (let i = 0; i < buffer.length; i += 3) {
    buffer[i] = data[offset];
    buffer[i + 1] = data[offset + 1];
    buffer[i + 2] = data[offset + 2];

    offset += 4;
  }

  return tf.tensor4d(buffer, [1, height, width, 3]);
}

const App = () => {
  const [model, setModel] = useState(null);
  const [predictions, setPredictions] = useState(null);
  const [image, setImage] = useState();

  useEffect(() => {
    const loadModel = async () => {
      // Carregando modelo
      await tf.ready();
      let model;
      try {
        model = await tf.loadLayersModel(
          bundleResourceIO(modelJson, modelWeights)
        );
      } catch (e) {
        console.log(e);
      }

      setModel(model);
    };
    loadModel();
  }, []);

  const classifyImage = async (uri) => {
    if (!uri) return;
    try {
      const resizedPhoto = await manipulateAsync(
        uri,
        [
          {
            resize: {
              width: picInputShapeSize.width,
              height: picInputShapeSize.height,
            },
          },
        ],
        { format: "jpeg", base64: true }
      );
      const base64 = resizedPhoto.base64;
      const arrayBuffer = Uint8Array.from(atob(base64), (c) => c.charCodeAt(0));
      const imageData = arrayBuffer;
      const imageTensor = imageToTensor(imageData); //decodeJpeg(imageData);
      const p = await classify(model, imageTensor);
      //setPredictions(p[0]);
      console.log(p);
    } catch (e) {
      console.log(e);
    }
  };

  const onHandlePick = async () => {
    let result = await ImagePicker.launchImageLibraryAsync({
      mediaTypes: ImagePicker.MediaTypeOptions.All,
      allowsEditing: true,
      quality: 1,
    });

    if (!result.canceled) {
      setImage(result.assets[0].uri);
    }
  };

  return (
    <View>
      <Image
        source={{ uri: image }}
        style={{ width: 200, height: 200 }}
        onLoad={() => classifyImage(image)}
      />
      <Button title="pick and predict" onPress={onHandlePick} />
      {predictions &&
        predictions.map((prediction, index) => (
          <Text key={index}>{prediction}</Text>
        ))}
    </View>
  );
};

export default App;
const NSFW_CLASSES = {
  0: "Drawing",
  1: "Hentai",
  2: "Neutral",
  3: "Porn",
  4: "Sexy",
};

export async function getTopKClasses(logits, topK) {
  const values = await logits.data();

  const valuesAndIndices = [];
  for (let i = 0; i < values.length; i++) {
    valuesAndIndices.push({ value: values[i], index: i });
  }
  valuesAndIndices.sort((a, b) => {
    return b.value - a.value;
  });
  const topkValues = new Float32Array(topK);
  const topkIndices = new Int32Array(topK);
  for (let i = 0; i < topK; i++) {
    topkValues[i] = valuesAndIndices[i].value;
    topkIndices[i] = valuesAndIndices[i].index;
  }

  const topClassesAndProbs = [];
  for (let i = 0; i < topkIndices.length; i++) {
    topClassesAndProbs.push({
      className: NSFW_CLASSES[topkIndices[i]],
      probability: topkValues[i],
    });
  }
  return topClassesAndProbs;
}

export const classify = async (model, img, topk = 5) => {
  const logits = model.predict(img);
  const classes = await getTopKClasses(logits, topk);
  logits.dispose();
  return classes;
};

this is the predict response when I teste with 1000000%%% nsfw image

[{"className": "Drawing", "probability": 0.5907529592514038}, {"className": "Hentai", "probability": 0.223214790225029}, {"className": "Neutral", "probability": 0.12099546194076538}, {"className": "Porn", "probability": 0.055417921394109726}, {"className": "Sexy", "probability": 0.009618803858757019}]

I currently had to downgrade tfjs-core, follow the explanation. (the current version is 4.2.0 and I moved to 4.1.0

tensorflow/tfjs#7273

edit: I can't confirm but I was also having a problem with tensorflow and using yarn resolve. But I could be wrong.

can you create a repo or drop a zipped download link for that?

from nsfwjs-mobile.

Related Issues (7)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.