- 21 Haz 2015
- 237
- 58
TensorFlow.js ile Yapay Zeka Geliştirmek
Merhaba dostlar. Bu yazımda sizlere TensorFlow.js kullanarak nasıl webde yapay zeka uygulamaları geliştirebilirsiniz onu anlatıyor olacağım. Öncelikle nedir bu TensorFlow bununla başlayalım.Nedir Bu TensorFlow ?
Tensorflow, Google tarafından yıllar süren bir çalışma sonucunda oluşturulmuş, yapay zekanın derin öğrenme çalışmaları yapan geliştiriciler için üretilmiş, 2015 yılından beri kullanıcıların kullanımına açılmış açık kaynaklı bir kütüphanedir. İlk olarak sadece Python kullanılarak geliştirilmiş olan bu framework, günümüzde Pyhton’un yanında JavaScript, R, C#, C++ gibi akıllara gelebilecek en popüler yazılım dilleri tarafından desteklenmiş durumdadır. Yazılım dillerinin bu desteği TensorFlow’u herhangi bir yazılım diline hakim olan yazılım geliştiricilerin rahat bir şekilde kullanmasına olanak sağlamaktadır. TensorFlow’un bu kadar bilinen ve kullanılan bir kütüphane olmasının da temel sebebi budur.TensorFlow'u anladık. Bu yazıda ise üstünde duracağımız konu bu kütüphanenin Javascript desteği olacak. Artık web geliştiricileri içinde Yapay Zekanın önü açılmış oldu
Eğer işin sıkıcı tarafını anladıysak şimdi gelin ufak bir örnek yaparak konuyu daha iyi anlamaya çalışalım.
Let's GO!
Burada yapacağımız örnek Yüz İfadelerini tahmin etmek. Bunun için uygulamaya bir fotoğraf vereceğiz ve ondan fotoğraftaki insana hangi duygu hakimse bize onu söyleyecek.Şimdi burada bazı adımlar var bunlar için sırayla gidelim.
1) Image Prep
Burada amaç fotoğrafı yazılım anlayacağı formata sokmak. Bizler gözlerimizle normal bir şekilde gözlem yapıp, bu gözlemleri sonuçlandırabiliyoruz ancak yazılımlar bu şekilde çalışmaz. Onların daha farklı standartları vardır. Bu adımda Yazılımın standardına uygun fotoğraflar initilaze etmek.
JavaScript:
import { tf } from './tf'
const NORMALIZATION_OFFSET = tf.scalar(127.5)
export const prepImg = (img, size) => {
const imgTensor = tf.fromPixels(img)
const normalized = imgTensor
.toFloat()
.sub(NORMALIZATION_OFFSET)
.div(NORMALIZATION_OFFSET)
if (imgTensor.shape[0] === size && imgTensor.shape[1] === size) {
return normalized
}
const alignCorners = true
return tf.image.resizeBilinear(normalized, [size, size], alignCorners)
}
export const rgbToGrayscale = async imgTensor => {
const minTensor = imgTensor.min()
const maxTensor = imgTensor.max()
const min = (await minTensor.data())[0]
const max = (await maxTensor.data())[0]
minTensor.dispose()
maxTensor.dispose()
const normalized = imgTensor.sub(tf.scalar(min)).div(tf.scalar(max - min))
let grayscale = normalized.mean(2)
return grayscale.expandDims(2)
}
Burada pikselleri [0, 255] ile [-1, 1] boyutları arasına alarak ml modelleri uygun hale getirdik.
2) Face Detection
Duyguları belirlemeden önce görüntüdeki insanları/yüzleri bulmalıyız. Bunun için yüz tanıma için Tensorflow.js üzerine kurulmuş bir kitaplık olan face-api.js kullanıyoruz.
JavaScript:
import * as faceapi from 'face-api.js'
const MODEL_PATH =
`${process.env.PUBLIC_URL}/static/models/face/` +
'mtcnn_model-weights_manifest.json'
const PARAMS = {
minFaceSize: 50,
scaleFactor: 0.709,
maxNumScales: 10,
scoreThresholds: [0.7, 0.7, 0.7],
}
export class FaceFinder {
constructor(path = MODEL_PATH, params = PARAMS) {
this.path = path
this.params = params
}
async load() {
this.model = new faceapi.Mtcnn()
await this.model.load(this.path)
}
async findFaces(img) {
const input = await faceapi.toNetInput(img, false, true)
const results = await this.model.forward(input, this.params)
const detections = results.map(r => r.faceDetection)
return { input, detections }
}
async findAndExtractFaces(img) {
const { input, detections } = await this.findFaces(img)
const faces = await faceapi.extractFaces(input.inputs[0], detections)
return { detections, faces }
}
}
Face Detection kısmı ile alakalı daha fazla şeyi merak ediyorsanız şu makaleyi inceleyebilirsiniz.
3) Emotion Classification
Şimdi birincil aktivite zamanı, duyguları sınıflandırmak. Bunun için, yedi duygusal durumdan (Kızgın, İğrenme, Korku, Mutlu, Üzgün, Sürpriz, Nötr) uygulama tarafından kategorize edilen yüzlerin görüntülerini içeren FER-2013 veri kümesinde eğitilmiş açık kaynaklı bir CNN modeli kullanıyorum . Bu model Python'da oluşturuldu, bu yüzden Keras modelini web dostu bir biçime dönüştürmek için bu tfjs dönüştürücü aracını kullandım.Modellere erişmek için buraya tıklayın.
4) FrontEnd
Geldik projemizin son kullanıcıyı ilgilendiren kısma. Burada React kullanarak bir app.js yazdım ve yaptığım işlemlerin görüntüsünü ekrana aldım kısacası.
JavaScript:
import debounce from 'lodash.debounce'
import React, { Component } from 'react'
import Dropzone from 'react-dropzone'
import Footer from './Footer'
import Header from './Header'
import Message from './Message'
import Results from './Results'
import sampleImg from '../img/sample.jpg'
import { FaceFinder } from '../ml/face'
import { EmotionNet } from '../ml/models'
import { readFile, nextFrame, drawBox, drawText } from '../util'
class App extends Component {
state = {
ready: false,
loading: false,
imgUrl: sampleImg,
detections: [],
faces: [],
emotions: [],
}
componentDidMount() {
this.initModels()
window.addEventListener('resize', this.handleResize)
}
componentWillUnmount() {
window.removeEventListener('resize', this.handleResize)
}
initModels = async () => {
const faceModel = new FaceFinder()
await faceModel.load()
const emotionModel = new EmotionNet()
await emotionModel.load()
this.models = { face: faceModel, emotion: emotionModel }
this.setState({ ready: true }, this.initPredict)
}
initPredict = () => {
if (!this.img || !this.img.complete) return
this.setState({ loading: true })
this.analyzeFaces()
}
handleImgLoaded = () => {
this.clearCanvas()
this.analyzeFaces()
}
handleResize = debounce(() => this.drawDetections(), 100)
handleUpload = async files => {
if (!files.length) return
const fileData = await readFile(files[0])
this.setState({
imgUrl: fileData.url,
loading: true,
detections: [],
faces: [],
emotions: [],
})
}
analyzeFaces = async () => {
await nextFrame()
if (!this.models) return
// get face bounding boxes and canvases
const faceResults = await this.models.face.findAndExtractFaces(this.img)
const { detections, faces } = faceResults
// get emotion predictions
let emotions = await Promise.all(
faces.map(async face => await this.models.emotion.classify(face))
)
this.setState(
{ loading: false, detections, faces, emotions },
this.drawDetections
)
}
clearCanvas = () => {
this.canvas.width = 0
this.canvas.height = 0
}
drawDetections = () => {
const { detections, emotions } = this.state
if (!detections.length) return
const { width, height } = this.img
this.canvas.width = width
this.canvas.height = height
const ctx = this.canvas.getContext('2d')
const detectionsResized = detections.map(d => d.forSize(width, height))
detectionsResized.forEach((det, i) => {
const { x, y } = det.box
const { emoji } = emotions[i][0].label
drawBox({ ctx, ...det.box })
drawText({ ctx, x, y, text: emoji })
})
}
render() {
const { ready, imgUrl, loading, faces, emotions } = this.state
const noFaces = ready && !loading && imgUrl && !faces.length
return (
<div className="px2 mx-auto container app">
<Header />
<main>
<div className="py1">
<Dropzone
className="btn btn-small btn-primary btn-upload bg-black h5"
accept="image/jpeg, image/png"
multiple={false}
disabled={!ready}
onDrop={this.handleUpload}
>
Upload image
</Dropzone>
</div>
{imgUrl && (
<div className="relative">
<img
ref={el => (this.img = el)}
onLoad={this.handleImgLoaded}
src={imgUrl}
alt=""
/>
<canvas
ref={el => (this.canvas = el)}
className="absolute top-0 left-0"
/>
</div>
)}
{!ready && <Message>Loading machine learning models...</Message>}
{loading && <Message>Analyzing image...</Message>}
{noFaces && (
<Message bg="red" color="white">
<strong>Sorry!</strong> No faces were detected. Please try another
image.
</Message>
)}
{faces.length > 0 && <Results faces={faces} emotions={emotions} />}
</main>
<Footer />
</div>
)
}
}
export default App
Burada tanımlanan yüzlere canvas kullanarak kutular koyuyuorum ve buradan duygu anlama işlemi devam ediyor.
Son düzenleme: