텐서플로우가 뭔가요?
머신러닝과 인공지능의 시대가 성큼 다가왔죠.
일반인들도 기계학습을 쉽게 프로그래밍할 수 있도록 해주는
텐서플로우를 직접 코딩해가며 알아봅시다.
특별히 뭔가 설치해야 할 필요 없도록
구름IDE를 사용해서 코딩을 진행합니다.
아래 코드들을 복붙하고 분석해가며 학습해보세요. 😀
🔗 Tensorflow 바로가기
🔗 구름IDE 바로가기
데이터 생성 자바스크립트 코드
// 인자로 주어진 설정에 따른 임의의 데이터 생성
const createData = ({xMin, xMax, weight, bias, count}) => {
const xArray = []
const yArray = []
for (let i = 0; i < count; i++) {
let yValue = 0
const xValue = Math.round((xMin + Math.random() * (xMax - xMin)) * 10) / 10
xArray.push(xValue)
yValue += xValue * (weight * randomOffset(0.05));
yValue += bias * randomOffset(0.005)
yValue = Math.round(yValue * 10) / 10
yArray.push(yValue)
}
return {
xAry: xArray,
yAry: yArray
}
}
// 주어진 범위 이내의 오차값 적용
const randomOffset = (max) => {
const offset = max * Math.random() * (Math.random() > 0.5 ? 1 : -1)
return 1 + offset
}
const resultData = createData({
xMin: 0, // x 최소값
xMax: 25, // x 최대값
weight: 3.2, // 기울기
bias: 256, // x = 0시 y좌표
count: 100 // 생성할 점 갯수
})
// 주피터 노트북에 붙여넣을 것
console.log(`x = [${resultData.xAry}]\ny = [${resultData.yAry}]`)
// 플라스크 웹앱에 붙여넣을 것
console.log(resultData.xAry.toString())
console.log(resultData.yAry.toString())
선형회귀 학습
순수 Tensorflow 코드
# 모듈 로드
import tensorflow as tf
import matplotlib.pyplot as plt
# 주어진 데이터 입력
# 아래 리스트에 생성된 데이터를 대체해 넣으세요.
x = [3, 4.4, 6.2, 7.5, 9.3]
y = [2.1, 4.2, 5.9, 8.3, 9.8]
# 데이터 시각화
plt.scatter(x, y, label="input data set")
# 선형 모델 클래스
class LinearModel:
def __call__(self, x):
return self.Weight * x + self.Bias
def __init__(self):
self.Weight = tf.Variable(0.)
self.Bias = tf.Variable(0.)
# 오차(손실) 구하기 함수
def loss(y, pred):
return tf.reduce_mean(tf.square(y - pred))
# 학습 함수
def train(linear_model, x, y, lr):
with tf.GradientTape() as t:
current_loss = loss(y, linear_model(x))
lr_weight, lr_bias = t.gradient(current_loss, [linear_model.Weight, linear_model.Bias])
linear_model.Weight.assign_sub(lr * lr_weight)
linear_model.Bias.assign_sub(lr * lr_bias)
# 학습 진행
linear_model = LinearModel()
epochs = 10000
for epoch_count in range(epochs + 1):
real_loss = loss(y, linear_model(x))
train(linear_model, x, y, lr=0.003)
if epoch_count % 100 == 0:
print(f"{epoch_count}:: W:{linear_model.Weight.numpy()} b:{linear_model.Bias.numpy()} Loss: {real_loss.numpy()} ")
Keras를 사용한 코드
# 모듈 로드
import tensorflow as tf
import matplotlib.pyplot as plt
# 주어진 데이터 입력
# 아래 리스트에 생성된 데이터를 대체해 넣으세요.
x = [3, 4.4, 6.2, 7.5, 9.3]
y = [2.1, 4.2, 5.9, 8.3, 9.8]
# 데이터 시각화
plt.scatter(x, y, label="input data set")
layer0 = tf.keras.layers.Dense(units=1, input_shape=[1])
model = tf.keras.Sequential([layer0])
model.compile(loss='mean_squared_error',
optimizer=tf.keras.optimizers.Adam(0.5))
history = model.fit(x, y, epochs=5000, verbose=True)
weights = layer0.get_weights()
print('weight: {} bias: {}'.format(weights[0], weights[1]))
print('Prediction: {}'.format(model.predict([7])))
플라스크 웹앱 코드
❗아래의 파이썬 코드들은 동작을 보여주기 위해 간략히 짠 예시이며, 실제 제품을 프로그래밍할 때는 적합하지 않습니다.
application.py
from flask import Flask, render_template, request
import sys
import asyncio
import learner
application = Flask(__name__)
weightAndBias = None
xList = []
yList = []
learning = False
progress = ""
# learner 모듈을 사용하여 학습
def getWeightAndBias(epochs):
global weightAndBias
global learning
if not learning:
learning = True
weightAndBias = learner.learn(xList, yList, epochs)
learning = False
# 일반 접속시
@application.route("/")
def index():
return render(None)
# '학습하기' 요청시
@application.route("/learn", methods=['POST'])
def learn():
global xList
global yList
xList = xList + list(map(float, request.json['xList'].strip().split(",")))
yList = yList + list(map(float, request.json['yList'].strip().split(",")))
xList = xList[0: min(len(xList), len(yList))]
yList = yList[0: min(len(xList), len(yList))]
getWeightAndBias(int(request.json['epochs']))
return
# '예측하기' 요청시
@application.route("/predict", methods=['POST'])
def predict():
return render(float(request.form['x']))
# 데이터를 html 템플릿에 넣어 렌더링
def render(x):
global weightAndBias
global learning
formular = f"[학습중{learner.progress}] " if learning else ""
if weightAndBias is not None:
formular += f"y = { weightAndBias[0] } * x + { weightAndBias[1] }"
else:
formular += "학습된 수식이 없습니다."
predicted = "학습된 수식이 없습니다."
if (x is not None and weightAndBias is not None):
predicted = (weightAndBias[0] * x + weightAndBias[1])
return render_template(
"index.html",
formular=formular,
predicted=predicted
)
if __name__ == "__main__":
application.run(host='0.0.0.0', port=int(sys.argv[1]), debug=True)
learner.py
# 모듈 로드
import tensorflow as tf
# 선형 모델 클래스
class LinearModel:
def __call__(self, x):
return self.Weight * x + self.Bias
def __init__(self):
self.Weight = tf.Variable(0.)
self.Bias = tf.Variable(0.)
# 오차(손실) 구하기 함수
def loss(y, pred):
return tf.reduce_mean(tf.square(y - pred))
# 학습 함수
def train(linear_model, x, y, lr):
with tf.GradientTape() as t:
current_loss = loss(y, linear_model(x))
lr_weight, lr_bias = t.gradient(
current_loss, [linear_model.Weight, linear_model.Bias]
)
linear_model.Weight.assign_sub(lr * lr_weight)
linear_model.Bias.assign_sub(lr * lr_bias)
# 학습 경과 표시 문자열
progress = ""
# 학습 실행 함수
def learn(xList, yList, epochs):
linear_model = LinearModel()
global progress
for epoch_count in range(epochs + 1):
real_loss = loss(yList, linear_model(xList))
train(linear_model, xList, yList, lr=0.003)
progress = f": {epoch_count}/{epochs}"
if epoch_count % 100 == 0:
print(
f"{epoch_count}:: W:{linear_model.Weight.numpy()}" +
f" b:{linear_model.Bias.numpy()} Loss: {real_loss.numpy()} "
)
progress = ""
return (linear_model.Weight.numpy(), linear_model.Bias.numpy())
/templates/index.html
<!doctype html>
<html lang="ko">
<head>
<title>선형회귀 예측</title>
<style>
body { padding: 24px; }
textarea, input { padding: 6px; }
textarea { width: 480px; height: 80px; }
</style>
<script>
function sendDataToLearn () {
var xhr = new XMLHttpRequest();
xhr.open("POST", "/learn", true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send(JSON.stringify({
xList: document.getElementById("xListInput").value,
yList: document.getElementById("yListInput").value,
epochs: document.getElementById("epochs").value
}));
location.href = "/";
}
</script>
</head>
<body>
<h1>선형회귀 예측</h1>
<h2>데이터 입력</h2>
<textarea id="xListInput" placeholder="x축 데이터들을 쉼표로 구분하여 입력하세요."></textarea>
<br>
<textarea id="yListInput" placeholder="y축 데이터들을 쉼표로 구분하여 입력하세요."></textarea>
<br>
<input id="epochs" placeholder="횟수" type="number" value="10000"/>
<br><br>
<button onclick="sendDataToLearn();">학습하기</button>
<br>
<br>
<form action="{{ url_for('predict') }}" method="post">
<input name="x" type="number" placeholder="x값 입력"/>
<br><br>
<input type="submit" value="예측하기"/>
</form>
<br><br>
<h2>학습된 수식</h2>
{{ formular }}
<br><br>
<h2>예측된 y값</h2>
{{ predicted }}
</body>
</html>
🍿 더 자세한 내용은 영상에서 보실 수 있습니다.
유튜브에서 영상 보기