Skip to main content

3 posts tagged with "python"

View All Tags

Introducing Flet - The Python Framework That Takes Inspiration from Flutter

· 4 min read
Alex Han
Software Engineer

image

At a time when mobile app development has become the norm, it's not surprising to see an increasing number of frameworks that make the process more efficient. One such framework is Flet, a Python-based framework that enables developers to build native iOS and Android apps using a single codebase. In this article, i will delve into the world of Flet and explore its origins, characteristics, and usage. I will also compare Flet with another popular framework, Flutter, to understand how they differ and where Flet shines.

What is Flet and why was it made first?

Flet was first introduced in 2019 by a group of Japanese developers looking to create a Python framework that took inspiration from Flutter's unique approach to building user interfaces. The framework quickly gained popularity within the Python community, and today, it boasts an active community of contributors and users.

The primary goal of Flet is to simplify the development process by enabling developers to write code once and deploy it on both iOS and Android platforms. Flet is built on top of popular Python frameworks such as Flask and Kivy, making it easy to integrate with other Python libraries.

The characteristics of Flet

At its core, Flet is designed to be simple, intuitive, and flexible. Here are some of the key characteristics of the framework:

  • Declarative Syntax: Like Flutter, Flet uses a declarative syntax that allows developers to describe the user interface in a simple and concise manner.
  • Hot Reload: Flet's hot reload feature allows developers to make changes to the code and see the results in real-time, without the need to restart the application.
  • Widgets: Flet uses a widget-based system, similar to Flutter, to build the user interface. Widgets are reusable building blocks that can be combined to create complex UI elements.
  • Material Design: Flet is built on top of Google's Material Design, making it easy for developers to create beautiful and consistent user interfaces.
  • Pythonic: Flet follows Pythonic principles, making it easy for Python developers to learn and use the framework.

Comparing Flet with Flutter

image2

  1. Language

The primary difference between Flet and Flutter is the programming language used. Flutter uses the Dart programming language, while Flet uses Python. For Python developers, Flet provides a more accessible option.

  1. Syntax

Flet's syntax is more intuitive and straightforward compared to Flutter. Python developers will find Flet's syntax more familiar, making it easier to learn and use.

  1. Customizability

Both Flet and Flutter are highly customizable, but Flet provides more flexibility due to Python's dynamic nature. Python developers can leverage their existing skills to create more complex and customized apps.

Examples of how to use Flet

Now that I've explored some of the characteristics of Flet, let's take a look at example of how to use the framework. I'll compare Flet to Flutter to highlight the similarities and differences between the two frameworks.

from flet import Text, TextField, Button

class LoginScreen:
def build(self):
return Column(
children=[
Text('Login'),
TextField('Username'),
TextField('Password'),
Button('Login')
]
)

And here's the equivalent code in Flutter

import 'package:flutter/material.dart';

class LoginScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Column(
children: [
Text('Login'),
TextField(
decoration: InputDecoration(hintText: 'Username'),
),
TextField(
decoration: InputDecoration(hintText: 'Password'),
),
ElevatedButton(
onPressed: () {},
child: Text('Login'),
),
],
);
}
}

As you can see, the code in Flet is very similar to the code in Flutter. Both frameworks use widgets to build the user interface, and the code is easy to read and understand.

Flutter can also be used to build a app, but developers may need to spend more time learning the framework and the Dart language before they can start building.

Conclusion

if you are a Python developer and want to start building mobile applications, flet is an excellent choice. It provides a lot of useful features and widgets, as well as comprehensive documentation, making it easy for beginners to get started quickly. Additionally, flet's similarity to flutter makes it easy to switch between the two libraries, allowing developers to choose the one that best suits their needs.

ChatGPT Automate Task Using Python

· 4 min read
Alex Han
Software Engineer

배경

ChatGPT 에 대해 일론머스크가 ChatGPT 무섭다고 한 기사를 읽고 간단히 사용해 본 후기.

ChatGPT Automation

ChatGPT 란 무엇인가?

ChatGPT는 OpenAI가 개발한 프로토타입 대화형 인공지능 챗봇이다. GPT-3.5 언어모델 기반으로 만들어졌고 지도학습, 강화학습 모두 사용해 파인 튜닝되었습니다.(현재 기준이고 계속 발전될 걸로 보임.)

사용 예시

matplotlib

chatGPT 싸이트에 try chatgpt를 클릭해 바로 사용할 수 있습니다.(로그인을 해야 하므로 사전에 가입해야 함.) 로그인을 하고 나면 채팅창 같이 뜨는데 채팅 창에 plot a linear regression with Python using matplotlib 을 쳐 보았습니다.

chatgpt_matplotlib

import matplotlib.pyplot as plt

# create some fake data
x = [1, 2, 3, 4, 5]
y = [2, 3, 4, 5, 6]

# fit a linear regression model
slope, intercept = np.polyfit(x, y, 1)

# predict the y-values of a line with the fitted model
predictions = [slope * i + intercept for i in x]

# plot the data points and the fitted line
plt.scatter(x, y)
plt.plot(x, predictions)

plt.show()

위와 같이 개발을 위한 코드를 생성해 줍니다.

실제로 사용 가능한지 체크 해 보면 np 가 undefined 로 뜨지만 이 정도는 matplotlib, pandas, numpy를 써 봤다면 자주 보는 축약어 numpy의 np 임을 바로 유추할 수 있습니다. 그래서 numpy를 import해 실행해 보면 정상 동작함을 볼 수 있습니다.

matplotlib_codetest

send message

이번엔 whatsapp 으로 메시지를 보내도록 send a message on Whatsapp using Python and pywhatkit 쳐 봤습니다.

send_whatsapp

기존에 구글에서 검색해 스택오버플로우를 찾거나 공식 문서를 뒤적여 봐야 했지만 이제는 라이브러리를 어떻게 사용하는지까지 한줄 타이핑으로 알 수 있습니다.

scraping

이번엔 웹싸이트를 스크래핑을 위해 web scrape https://books.toscrape.com/ using Python and beautiful soup 를 쳐보자.(해당 명령은 잘 동작하지만 다른 웹 싸이트는 잘 동작하지 않을 수 있음. 사용 방법은 맞게 구현됨.)

webscrape_gpt

실제 코드에서 실행해 보면

webscrape

잘 동작합니다.

결론

무료로 배포되어 있기 때문에 구글 검색이 귀찮고 따분해진 사람들은 새로운 검색엔진 형태로 사용해 보는 것도 좋아 보입니다.(개인적으로는 마이크로소프트에서 만든 copilot 보다 나아 보임.) 인공지능의 자연어 처리 모델이 얼마나 발전한지 경험해 볼 수 있는 귀한 시간이었습니다.

How to Train and Optimize A Neural Network

· 7 min read
Alex Han
Software Engineer

배경

deep learning을 할 줄 아냐고 항상 부담이 된다. 이름부터 어려워 보이는 deep learning 에 대해 pytorch 라이브러리를 활용해 간단히 사용 방법을 알아보자.

Deep Learning

딥러닝은 머신 러닝의 하위 집합으로, 특히 사람의 뇌 구조와 기능에서 영감을 얻은, 알고리즘을 포함한 대량의 데이터를 다룹니다. 그래서 딥러닝 모델을 종종 심층 신경망이라고 부르는 것입니다.

Dataset

복잡하고 수 많은 작업이 필요한 데이터 전처리 과정들은 제외하기 위해 small iris dataset 활용.

Load Data with Data Loader

import warnings
warnings.filterwarnings("ignore")

import numpy as np
import pandas as pd
import torch
import torch.nn as nn
import torch.nn.functional as F
from torch.utils.data import DataLoader, TensorDataset
from sklearn.model_selection import train_test_split

import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
from IPython import display
display.set_matplotlib_formats("svg")

iris = pd.read_csv("https://gist.githubusercontent.com/netj/8836201/raw/6f9306ad21398ea43cba4f7d537619d0e07d5ae3/iris.csv")
iris.head()

head() 메서드를 활용해 dataset의 컬럼과 실제값을 간단히 확인합니다.

iris_head

딥러닝을 통해 예측할 목표는 variety 컬럼이다. 다른 4개의 컬럼에 따라 이 컬럼의 값이 변경된다고 보면 됩니다. 수식으로 생각하면 4개의 컬럼을 X, 목표로 하는 예측값을 y로 해서 생각해 봅니다.

X = torch.tensor(iris.drop("variety", axis=1).values, dtype=torch.float)
y = torch.tensor(
[0 if vty == "Setosa" else 1 if vty == "Versicolor" else 2 for vty in iris["variety"]],
dtype=torch.long
)

print(X.shape, y.shape)

위의 코드와 같이 불러온 데이터에서 variety 컬럼을 제거한 것을 X, variety 만 불러온 것을 y로 합니다. 이 때 variety 컬럼의 값들 중 Setosa를 0, Versicolor를 1, 나머지를 2로 변환해 줍니다.

Train / Test split

이제 training할 데이터들과 실제 이를 검증할 test 데이터들을 나누어 줍니다. 미리 import 해 둔 from sklearn.model_selection import train_test_split 라이브러리를 사용하면 됩니다.

X_train, X_test, y_train, y_test = train_test_split(X, y, train_size=0.8, random_state=42)

train_data = TensorDataset(X_train, y_train)
test_data = TensorDataset(X_test, y_test)

train_loader = DataLoader(train_data, shuffle=True, batch_size=12)
test_loader = DataLoader(test_data, batch_size=len(test_data.tensors[0]))

print("Training data batches:")
for X, y in train_loader:
print(X.shape, y.shape)

print("\nTest data batches:")
for X, y in test_loader:
print(X.shape, y.shape)

Training

딥러닝을 위해 만들 모델은 input layer과 output layer를 연결하는 16개의 노드와 단일 hidden layer를 활용합니다.

class Net(nn.Module):
def __init__(self):
super().__init__()
self.input = nn.Linear(in_features=4, out_features=16)
self.hidden_1 = nn.Linear(in_features=16, out_features=16)
self.output = nn.Linear(in_features=16, out_features=3)

def forward(self, x):
x = F.relu(self.input(x))
x = F.relu(self.hidden_1(x))
return self.output(x)


model = Net()
print(model)

모델을 만들었으니 이제 training을 시작하는데 반복 동작하면서 오차를 줄여가는 과정을 수행하게 됩니다. Crossentropyloss를 사용해 오차를 추적하고 Adam으로 경사 하강 과정을 진행합니다.

num_epochs = 200
train_accuracies, test_accuracies = [], []

loss_function = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(params=model.parameters(), lr=0.01)

for epoch in range(num_epochs):
# Train set
for X, y in train_loader:
preds = model(X)
pred_labels = torch.argmax(preds, axis=1)
loss = loss_function(preds, y)
optimizer.zero_grad()
loss.backward()
optimizer.step()
train_accuracies.append(
100 * torch.mean((pred_labels == y).float()).item()
)

# Test set
X, y = next(iter(test_loader))
pred_labels = torch.argmax(model(X), axis=1)
test_accuracies.append(
100 * torch.mean((pred_labels == y).float()).item()
)

데이터가 작아 금방 완료되는데요. 반복 동작의 횟수 당 정확도가 어떻게 나왔었는지 시각화를 통해 보게 되면 아래와 같습니다.

fig = plt.figure(tight_layout=True)
gs = gridspec.GridSpec(nrows=2, ncols=1)

ax = fig.add_subplot(gs[0, 0])
ax.plot(train_accuracies)
ax.set_xlabel("Epoch")
ax.set_ylabel("Training accuracy")

ax = fig.add_subplot(gs[1, 0])
ax.plot(test_accuracies)
ax.set_xlabel("Epoch")
ax.set_ylabel("Test accuracy")

fig.align_labels()
plt.show()

visualize

Optimization

  1. 우선 트레이닝 과정을 아래와 같이 단순화합니다.
losses = []
def train_model(train_loader, test_loader, model, lr=0.01, num_epochs=200):
train_accuracies, test_accuracies = [], []
loss_function = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(params=model.parameters(), lr=lr)

for epoch in range(num_epochs):
for X, y in train_loader:
preds = model(X)
pred_labels = torch.argmax(preds, axis=1)
loss = loss_function(preds, y)
losses.append(loss.detach().numpy())
optimizer.zero_grad()
loss.backward()
optimizer.step()

train_accuracies.append(
100 * torch.mean((pred_labels == y).float()).item()
)

X, y = next(iter(test_loader))
pred_labels = torch.argmax(model(X), axis=1)
test_accuracies.append(
100 * torch.mean((pred_labels == y).float()).item()
)

return train_accuracies[-1], test_accuracies[-1]


train_model(train_loader, test_loader, Net())
  1. layer 개수를 조절할 수 있는 새로운 모델 클래스를 생성합니다.
class Net2(nn.Module):
def __init__(self, n_units, n_layers):
super().__init__()
self.n_layers = n_layers

self.layers = nn.ModuleDict()
self.layers["input"] = nn.Linear(in_features=4, out_features=n_units)

for i in range(self.n_layers):
self.layers[f"hidden_{i}"] = nn.Linear(in_features=n_units, out_features=n_units)

self.layers["output"] = nn.Linear(in_features=n_units, out_features=3)

def forward(self, x):
x = self.layers["input"](x)

for i in range(self.n_layers):
x = F.relu(self.layers[f"hidden_{i}"](x))

return self.layers["output"](x)
  1. layer를 1~4개까지 증가시켜 보고 각 layer가 8, 16, 24, 32, 40, 48, 56개 노드를 각각 가졌을 때 어떻게 변화하는지 지켜봅니다.
n_layers = np.arange(1, 5)
n_units = np.arange(8, 65, 8)
train_accuracies, test_accuracies = [], []

for i in range(len(n_units)):
for j in range(len(n_layers)):
model = Net2(n_units=n_units[i], n_layers=n_layers[j])
train_acc, test_acc = train_model(train_loader, test_loader, model)
train_accuracies.append({
"n_layers": n_layers[j],
"n_units": n_units[i],
"accuracy": train_acc
})
test_accuracies.append({
"n_layers": n_layers[j],
"n_units": n_units[i],
"accuracy": test_acc
})


train_accuracies = pd.DataFrame(train_accuracies).sort_values(by=["n_layers", "n_units"]).reset_index(drop=True)
test_accuracies = pd.DataFrame(test_accuracies).sort_values(by=["n_layers", "n_units"]).reset_index(drop=True)
test_accuracies.head()

accuracy

결과를 보면 테스트 정확도는 layer가 몇 개일 때 node가 몇 개일 때 어떤 양상을 보였는지 알 수 있고 test_accuracies[test_accuracies["accuracy"] == test_accuracies["accuracy"].max()] 를 통해 이 중 가장 정확도가 높은 layer, node 개수를 선정할 수 있습니다.

결론

iris dataset은 굉장히 적은 데이터이고 training이 굉장히 잘 되는 데이터이기에 이 과정이 무의미해 보이도록 정확도가 대부분이 정확도가 높게 나왔습니다.

하지만 실제 업무에서는 이처럼 깨끗하지 않고 깨끗하더라도 경향성이 일관되지 않아 그 수식을 찾아내기 힘든 경우가 대다수기 때문에 이와 같은 과정들이 필요합니다. layer, node 개수를 조정해 보는 것 외에도 변수들을 조절해 모델에 변화를 주거나 training 방식의 변화를 주어 optimization을 한다면 보다 의미있는 값들을 도출할 수 있을 거라 생각합니다.

이 글을 쓰면서 딥러닝에 좀 더 자신감을 가질 수 있으면 좋겠다 나도..;