반응형

오늘은 파이썬(Python) 파이토치(PyTorch)에서 자연어를

처리하기 위해서 우선적으로 해야 할 토큰 만들기를 알아보겠습니다.

자연어를 처리하기 위해서는 단어를 구분해서

문장을 해석해야 합니다.

 

간단하게 문장과 공백으로도 나눌 수 있지만

정확한 의미를 확인하기 위해서는 문장과 공백만을

구분해서는 사용하기 힘듭니다.

 

NLP 작업에 사용되는 말뭉치(corpus)는 원시 텍스트와

메타데이터로 구성됩니다.

원시 텍스트, 메타데이터를 구분하기 위해서

오픈 소스 NLP 패키지는 대부분 코큰화 기능을 지원합니다.

대표적인 NLP 두가지 제품을 사용해서 토큰화를 확인해보겠습니다.

 

첫 번째 오픈 NLP 패키지 spacy

https://spacy.io/

 

spaCy · Industrial-strength Natural Language Processing in Python

spaCy is a free open-source library for Natural Language Processing in Python. It features NER, POS tagging, dependency parsing, word vectors and more.

spacy.io

spacy를 사용하기 위해서는 먼저 패키지를 설정해야 합니다.

spacy는 패키지 설치 시간이 조금 오래 걸립니다.

import spacy

import를 사용해서 spacy 패키지를 로드합니다.

def spacyex():
    nlp = spacy.load('en_core_web_sm')

    # Process whole documents
    text = ("When Sebastian Thrun started working on self-driving cars at "
            "Google in 2007, few people outside of the company took him "
            "seriously. “I can tell you very senior CEOs of major American "
            "car companies would shake my hand and turn away because I wasn’t "
            "worth talking to,” said Thrun, in an interview with Recode earlier "
            "this week.")
    doc = nlp(text)

    # Analyze syntax
    print("Noun phrases:", [chunk.text for chunk in doc.noun_chunks])
    print("Verbs:", [token.lemma_ for token in doc if token.pos_ == "VERB"])

    # Find named entities, phrases and concepts
    for entity in doc.ents:
        print(entity.text, entity.label_)

spacy.load() 함수를 사용해서 core를 로드합니다.

text에 일반 문장으로 입력합니다.

nlp를 사용해서 토큰화를 진행합니다.

출력 결과 일반 문장을 토큰화 하여 출력합니다.

token.pos_를 사용하면 단어를 분류하여

품사 태깅을 확인할 수 있습니다.

혹 spacy를 사용 중 오류가 발생하면 아래 내용을 참고해주세요.

https://believecom.tistory.com/746

 

python spacy 모델 사용 중 Can't find model 'en_core_web_sm'. It doesn't seem to be a Python package 오류 처리 하기

python 자연어 처리를 공부하면서 spacy모델을 사용한 기본 테스트를 하게 되면 오류가 발생합니다. 오류 내용은 "Can't find model 'en_core_web_sm'. It doesn't seem to be a Python package" 입니다. 모델이..

believecom.tistory.com

 

두 번째 오픈 NLP 패키지 nltk

https://www.nltk.org/

 

Natural Language Toolkit — NLTK 3.6.2 documentation

Natural Language Toolkit NLTK is a leading platform for building Python programs to work with human language data. It provides easy-to-use interfaces to over 50 corpora and lexical resources such as WordNet, along with a suite of text processing libraries

www.nltk.org

nltk 패키지도 import를 사용해서 설치가 가능합니다.

nltk는 패키지 다운로드 후 컴파일을 진행하면

추가 패키지를 다운로드해야 합니다.

nltk.download() 함수를 사용해서 오류 발생 시

패키지를 하나씩 선택하면 됩니다.

def nltkex():
    nltk.download('punkt')
    nltk.download('averaged_perceptron_tagger')
    nltk.download('maxent_ne_chunker')
    nltk.download('words')
    nltk.download('treebank')
    sentence = """At eight o'clock on Thursday morning Arthur didn't feel very good."""
    tokens =nltk.word_tokenize(sentence)
    print(tokens)
    tagged = nltk.pos_tag(tokens)
    print(tagged[0:6])

    eltities = nltk.chunk.ne_chunk(tagged)
    print(eltities)

    t = treebank.parsed_sents('wsj_0001.mrg')[0]
    t.draw()

nltk.word_tokenize() 함수를 사용해서 토큰화를 진행합니다.

nltk.pos_tag()함수는 품사 태깅을 진행 후 

토큰 정보를 출력할 수 있습니다.

간단한 함수 사용으로 토큰화를 진행할 수 있습니다.

청크 나구기를 하기 위해서는 nltk.chunk.ne_chunk() 함수를 사용합니다.

간단한 출력으로 문장의 청크를 구분할 수 있습니다.

파이토치(PyTorch) 자연어 처리에서 토큰, 청크 단위로 문장을

구분하면 정확한 구조를 확인하기 위해서 트리구조가 가장 좋습니다.

nltk 패키지에서는 treebank를 사용해서 트리구조

내용을 확인할 수 있습니다.

자연어 처리에서 문장을 처리하기 위한

토큰화는 가장 기본되는 작업입니다.

두 가지 오픈 패키지를 사용해서 우선적인 자연어 처리

기본을 공부하면 좋겠습니다.

감사합니다.

 

반응형
반응형

python 자연어 처리를 공부하면서 spacy모델을

사용한 기본 테스트를 하게 되면 오류가 발생합니다.

오류 내용은 "Can't find model 'en_core_web_sm'.

It doesn't seem to be a Python package" 입니다.

모델이 'en'이 포함되어 있지 않은 것으로 확인됩니다.

오류를 해결하기 위해서 검색해보니까

추가 설치가 필요하다고 합니다.

"python -m spacy download en"

cmd를 실행해서 en 모델을 추가 설치하면

정상적으로 컴파일됩니다.

커멘드 실행 후 spacy 모델에서 추가 내용을 다운로드합니다.

컴파일하면 정상적으로 token 생성이 가능합니다.

반응형
반응형

파이썬(python)은 다수 스크립트 파일을 생성해서

프로젝트를 구성할 수 있습니다.

각 스크립트는 main을 추가할 수 있으면

함수 및 모든 데이터 정보를 저장할 수 있습니다.

오늘은 파이썬(python) 메인 스크립트에서

다른 스크립트를 호출하는 방법을 알아보겠습니다.

파이썬(python)에서는 스크립트 파일을

3가지 형태로 호출할 수 있습니다.

첫 번째 import 사용

import 함수는 패키지를 포함시키는 함수이지만

스크립트 파일도 포함시킬 수 있습니다.

item.py 신규 파일을 만들어서 2개의 함수를 정의합니다.

import 함수에 선택 파일 이름을 설정합니다.

,py 확장자는 빼주세요.

정상적으로 임포트 되었다면 파일명을 입력하면

스크립트에 저장된 함수를 확인할 수 있습니다.

컴파일하면 main 함수 및 item 스크립트 함수

정보가 출력됩니다.

 

두 번째 exec 사용

두 번째는 exec 함수를 사용해서

스크립트 파일을 직접 접근할 수 있습니다.

직접 함수를 사용하지 않고 메임 함수를 호출하는 구조로

import 함수 사용과는 조금 다릅니다.

새로운 스트립트 파일을 생성 후 main을

포함해서 함수를 작성해주세요.

버전이 낮은 파이썬(python)2 버전은

execfile() 함수를 사용하면 됩니다.

exec(open("item2.py").read())

exex를 사용하면 스크립트를 확인하고

main 함수를 바로 호출합니다.

 

세 번째 subprocess 사용

subprocess 모듈을 사용하면 새 프로세스를

생성하거나 출력을 반환할 수 있습니다.

subprocess를 사용하기 전에 모듈을 import 해주세요

subprocess.call("item2.py", shell=True)

subprocess 모듈을 사용해서 신규 스크립트 파일을

실행 후 main 실행 반환 값을 확인할 수 있습니다.

subprocess, exec 사용은 스크립트를

메인을 확인하는 구조이기 때문에

유틸리티 형태를 사용하고 싶다면

import를 사용해서 직접 접근하는 방식이

가장 좋은 방법입니다.

파이썬(python)을 공부하게 되면 정말 많은

유틸리티를 만날 수 있기 때문에

필요하다면 별도 저장 후 프로그램 

개발에 적극 활용해주세요.

감사합니다.

 

반응형
반응형

코틀린(Kotlin)을 사용 파일 탐색기 만들기는

다양한 컨트롤을 사용해서 개발 가능하지만

조금 더 자유롭게 리스트를 구성할 수 있는

RecyclerView를 사용해서 구현해보겠습니다.

 

RecyclerView는 인스타그램, 유튜브 피드, 전화번호부

등과 같이 동일한 형태의 뷰의 데이터에 따라서 자유롭게

구성할 수 있는 컨트롤입니다.

기존에는 ListView를 많이 사용했지만 커스터마이징이

힘든 단점이 부각되면서 RecyclerView를 많이 사용합니다.

 

먼저 파일 탐색기에서 가장 기본으로 사용하는

파일, 폴더 단위를 관리할 수 있는 Fragment를 구성해보겠습니다.

app 트리에서 filelist 패키지를 생성 후

FilesListFragment 코틀린(Kotlin) Class를 생성합니다.

class FilesListFragment : Fragment() {
   companion object {
        private const val ARG_PATH: String = "com.office.secuex"
        fun build(block:Builder.()-> Unit) = Builder().apply(block).build()
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return inflater.inflate(R.layout.fragment_files_list, container, false)
    }
}

companion object를 선언해서 블록안에

전역 변수를 지정합니다.

onCreateView 실행 시 infalter을 사용해서 레이아웃을 출력합니다.

inflater에 사용하기 위한 fragment_files_list.xml을 생성합니다.

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout  xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/filesRecyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScroolingViewBehavior" />

    <LinearLayout
        android:id="@+id/emptyFolderLayout"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:gravity="center"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <ImageView
            android:layout_width="200dp"
            android:layout_height="200dp"
            android:background="@drawable/background_circle"
            android:padding="40dp"
            android:src="@drawable/ic_folder_dark_24dp" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_marginTop="16dp"
            android:layout_height="wrap_content"
            android:textSize="16sp"
            android:textStyle="bold"
            android:text="There is nothing here!"/>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="12sp"
            android:text="Empty Folder."/>

    </LinearLayout>

</androidx.constraintlayout.widget.ConstraintLayout >

RectclerView 속성인 app:layout_hehavior은

최신 버전 형태로 변경해야 합니다.

build.gradle app 항목에 아래 내용을 추가합니다.

implementation("androidx.recyclerview:recyclerview:1.2.1")
implementation("androidx.recyclerview:recyclerview-selection:1.1.0")

패키지를 추가하면 RecyClerView를 사용할 수 있습니다.

아이템 정보를 연결할 수 있는 빌더 클래스를

FileListFragment에 추가합니다.

    class Builder{
        var path : String = ""
        fun build(): FilesListFragment{
            val fragment = FilesListFragment()
            val args = Bundle()
            args.putString(ARG_PATH, path)
            fragment.arguments = args;
            return fragment
        }
    }

모든 변수에 연결할 수 있는 Builder 클래스는

입력받은 FilesListFragment 정보를 연결합니다.

이제 생성한 FilesListFragment를 MainActivity에

연결해야 합니다.

 

  override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_secu_explorer)

        if( savedInstanceState == null)
        {
            val filesListFragment = FilesListFragment.build {
                path = Environment.getExternalStorageDirectory().absolutePath
            }

            supportFragmentManager.beginTransaction()
                .add( R.id.container, filesListFragment)
                .addToBackStack( Environment.getExternalStorageDirectory().absolutePath)
                .commit()
        }

savedInstanceState가 없을 경우

filesListFragment를 생성해서 백그라운드로 실행시킵니다.

MainActivity 레이아웃에 FrameLayout를 생성합니다.

 <FrameLayout
        app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScroolingViewBehavior"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/container">
    </FrameLayout>

FrameLayout 속성 중 app:layout_behavior을

최신 버전 형태로 변경합니다.

FrameLayout를 사용해서 Activity가 실행되면

RecyclerView를 실행할 수 있는 기본 구조를 모두 확인했습니다.

이번에는 RecyclerView에 들어갈 파일, 폴더 정보를

정리해보겠습니다.

common 폴더를 생성하고 FileType.kt 파일을 생성합니다.

파일 타입, 파일 모델을 확인할 수 있는 두 개의

클래스를 정의합니다.

package com.office.secuex.common

import java.io.File

enum class FileType {
    FILE,
    FOLDER;

    companion object{
        fun getFileType(file: File) = when(file.isDirectory){
            true -> FOLDER
            false -> FILE
        }
    }

}

data class FileModel(
    val path : String,
    val fileType : FileType,
    val name : String,
    val sizeInMB: Double,
    val extension: String ="",
    val subFiles: Int = 0
)

FileModel은 경로, 타입, 이름

사이즈, 확장자로 구분됩니다.

파일 경로, 용량, 파일 모델을 구성하기 위한

함수를 utils 패키지를 생성해서 정의합니다.

package com.office.secuex.utils

import com.office.secuex.common.FileModel
import com.office.secuex.common.FileType
import java.io.File

fun getFilesFromPath( path : String, showHiddenFiles : Boolean = false, onlyFolders:Boolean = false)
        : List<File>{
    val file = File(path)
    return file.listFiles()
        .filter { showHiddenFiles || !it.name.startsWith(".")}
        .filter { !onlyFolders || it.isDirectory}
        .toList()
}

fun getFileModelsFromFiles(files: List<File>) : List<FileModel>{
    return files.map {
        FileModel(it.path, FileType.getFileType(it), it.name,
        convertFileSizeToMB(it.length()), it.extension, it.listFiles()?.size?:0)
    }
}

fun convertFileSizeToMB(sizeInBytes: Long) : Double{
    return ( sizeInBytes.toDouble()) / (1024 * 1024)
}

getFilesFromPath() 함수를 사용해서

파일 리스트를 확인할 수 있습니다.

FilesListFragment에서 사용하는

RectclerView에 연결하기 위한

item_recycler_file.xml 레이아웃을 생성합니다.

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout  xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginBottom="1dp"
    android:background="@color/colorPrimary"
    android:foreground="?selectableItemBackground"
    android:padding="16dp">

    <TextView
        android:id="@+id/nameTextView"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:textSize="20sp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        tools:text="Pictuers" />

    <TextView
        android:id="@+id/folderTextView"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="(Folder)"
        android:textSize="12sp"
        android:visibility="gone"
        app:layout_constraintLeft_toLeftOf="@id/nameTextView"
        app:layout_constraintRight_toRightOf="@id/nameTextView"
        app:layout_constraintTop_toBottomOf="@id/nameTextView" />

    <TextView
        android:id="@+id/totalSizeTextView"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="4 MB"
        android:textSize="12sp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@id/folderTextView" />

</androidx.constraintlayout.widget.ConstraintLayout >

하단에 있는 참고 사이트와는 버전이 다르기 때문에

최신 버전은 ConstraintLayout를 사용해야 최신 버전에서

컴파일이 정상적으로 진행됩니다.

이제 RecyclerView에 정보를 연결할 수 있는

FilesRecyclerAdapter를 만들어 보겠습니다.

filelist 패키지 아래에 FilesRecyclerAdapter 클래스를 생성합니다.

package com.office.secuex.filelist

import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.office.secuex.R
import com.office.secuex.common.FileModel
import com.office.secuex.common.FileType
import androidx.recyclerview.widget.RecyclerView
import kotlinx.android.synthetic.main.item_recycler_file.view.*

class FilesRecyclerAdapter : RecyclerView.Adapter<FilesRecyclerAdapter.ViewHolder>() {

    var onItemClickListener: ((FileModel) -> Unit)? = null
    var onItemLongClickListener: ((FileModel) -> Unit)? = null

    var filesList = listOf<FileModel>()

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val view = LayoutInflater.from(parent.context).inflate(R.layout.item_recycler_file, parent, false)
        return ViewHolder(view)
    }

    override fun getItemCount() = filesList.size

    override fun onBindViewHolder(holder: ViewHolder, position: Int) = holder.bindView(position)

    fun updateData(filesList: List<FileModel>) {
        this.filesList = filesList
        notifyDataSetChanged()
    }

    inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), View.OnClickListener, View.OnLongClickListener {
        init {
            itemView.setOnClickListener(this)
            itemView.setOnLongClickListener(this)
        }

        override fun onClick(v: View?) {
            onItemClickListener?.invoke(filesList[adapterPosition])
        }

        override fun onLongClick(v: View?): Boolean {
            onItemLongClickListener?.invoke(filesList[adapterPosition])
            return true
        }

        fun bindView(position: Int) {
            val fileModel = filesList[position]
            itemView.nameTextView.text = fileModel.name

            if (fileModel.fileType == FileType.FOLDER) {
                itemView.folderTextView.visibility = View.VISIBLE
                itemView.totalSizeTextView.visibility = View.GONE
                itemView.folderTextView.text = "(${fileModel.subFiles} files)"
            } else {
                itemView.folderTextView.visibility = View.GONE
                itemView.totalSizeTextView.visibility = View.VISIBLE
                itemView.totalSizeTextView.text = "${String.format("%.2f", fileModel.sizeInMB)} mb"
            }
        }
    }
}

RectclerView.adapter을 사용해서

파일 및 폴더 정보를 접근할 수 있습니다.

마지막으로 MainActivity에 연결된

FilesListFragment에 Adapter를 연결합니다.

package com.office.secuex.filelist

import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.office.secuex.R
import com.office.secuex.common.FileModel
import com.office.secuex.common.FileType
import androidx.recyclerview.widget.RecyclerView
import kotlinx.android.synthetic.main.item_recycler_file.view.*

class FilesRecyclerAdapter : RecyclerView.Adapter<FilesRecyclerAdapter.ViewHolder>() {

    var onItemClickListener: ((FileModel) -> Unit)? = null
    var onItemLongClickListener: ((FileModel) -> Unit)? = null

    var filesList = listOf<FileModel>()

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val view = LayoutInflater.from(parent.context).inflate(R.layout.item_recycler_file, parent, false)
        return ViewHolder(view)
    }

    override fun getItemCount() = filesList.size

    override fun onBindViewHolder(holder: ViewHolder, position: Int) = holder.bindView(position)

    fun updateData(filesList: List<FileModel>) {
        this.filesList = filesList
        notifyDataSetChanged()
    }

    inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), View.OnClickListener, View.OnLongClickListener {
        init {
            itemView.setOnClickListener(this)
            itemView.setOnLongClickListener(this)
        }

        override fun onClick(v: View?) {
            onItemClickListener?.invoke(filesList[adapterPosition])
        }

        override fun onLongClick(v: View?): Boolean {
            onItemLongClickListener?.invoke(filesList[adapterPosition])
            return true
        }

        fun bindView(position: Int) {
            val fileModel = filesList[position]
            itemView.nameTextView.text = fileModel.name

            if (fileModel.fileType == FileType.FOLDER) {
                itemView.folderTextView.visibility = View.VISIBLE
                itemView.totalSizeTextView.visibility = View.GONE
                itemView.folderTextView.text = "(${fileModel.subFiles} files)"
            } else {
                itemView.folderTextView.visibility = View.GONE
                itemView.totalSizeTextView.visibility = View.VISIBLE
                itemView.totalSizeTextView.text = "${String.format("%.2f", fileModel.sizeInMB)} mb"
            }
        }
    }
}

컴파일을 진행하면 정상적으로 컴파일이 되면서

RecyclerView를 확인할 수 있어야 합니다.

그런데 Error가 발생하면서 컴파일이 안됩니다.

Error 내용은 파일에 접근을 할 수 없는 내용입니다.

스토리지 접근에 필요한 정보를 Manifest.xml에 추가했습니다.

 <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

권한을 추가해도 오류가 동일하게 발생합니다.

확인 결과 Application에 추가 권한 필요했습니다.

Application에 추가적으로 아래 속성을 추가합니다.

 android:requestLegacyExternalStorage="true"

자 그럼 다시 한번 컴파일을 해보겠습니다.

기본 스토리지 정보가 List에 출력되는 것을 확인할 수 있습니다.

코틀린(Kotlin)을 사용해서 리스트를 출력하기

위해서는 많은 코딩이 필요하지만

기본 내용을 이해하면 대부분 같은 패턴을 구성되기 때문에

한 번은 꼭 직접 코딩을 하면서 확인해주십시오.

저도 참고 내용을 확인하면서 진행했지만

버전 문제 따른 다양한 오류를 경험했습니다.

오늘은 코틀린(Kotlin)을 사용해서 파일 탐색기

기본 UI를 만들었습니다.

다음 시간에는 RecyclerView에서 이벤트

연동을 해보겠습니다.

감사합니다.

http://thetechnocafe.com/build-a-file-explorer-in-kotlin-part-2-reading-files-from-paths/

 

Build a File Explorer in Kotlin – Part 2 – Reading files from paths - TheTechnoCafe

In this tutorial you will read the list of files/folders on a given path and display them in a RecyclerView along with their size and meta data such as...

thetechnocafe.com

 

반응형
반응형

Android 프로그램을 개발하면서

최신 버전에서 발생하는 behavior 화면 스크롤하는

기능 오류를 발견했습니다.

해결법을 찾아 보니 최신 버전은

다른 코드를 사용해야 합니다.

<android.support.v7.widget.RecyclerView
android:id="@+id/filesRecyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />

@string/appbar_scrolling_view_behavior

속성을 사용하면

컴파일 시 Android resource linking failed

오류가 발생합니다.

   <android.support.v7.widget.RecyclerView
        android:id="@+id/filesRecyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScroolingViewBehavior" />

behavior 속성을

com.google.android.material.appbar.AppBarLayout$ScroolingViewBehavior

변경하면 컴파일되면서 오류가 해결됩니다.

감사합니다.

반응형
반응형

스마트폰을 사용해서 다양한 파일을

관리하기 위해서 파일 탐색기를 많이 사용합니다.

파일 탐색기는 저장된 스토리지

정보를 모두 확인하기 위한 다양한 기술이

필요하기 때문에 프로그램 개발에서는

반드시 알아야 하는 프로그램입니다.

 

오늘은 코틀린(Kotlin)을 사용한 파일, 폴더를

관리할 수 있는 파일 탐색기(explorer)를

알아보겠습니다.

 

일반적인 파일 탐색기 보다는 좋은 예제 소스가 있어

참고 예제 소스 기준으로 몇 회로 나누어 알아보겠습니다.

참고 사이트는 아래쪽에 링크를 걸었습니다.

 

먼저 안드로이드(Android)에서 파일 탐색을

하기 위한 Provider에 대해서 알아보겠습니다.

 

안드로이드는 Acrivity, Service,

Broadcast Receiver, Content Provider

4가지 구성요소로 구분됩니다.

 

Content Provider는 앱이 접근할 수 있는

모든 영구 저장 위치에 저장 가능한 앱 데이터의

공유형 집합을 관리합니다.

파일 시스템, SQLite, 데이터 관리

파일 읽기, 쓰기, 수정하기, 삭제하기 기능 관리

데이터 엑세스 권한에 대한 제어 기능

즉 파일을 접근하기 위해서는 Provider를 먼저 생성해야 합니다.

코틀린(Kotlin) 신규 프로젝트를 생성합니다.

AndroidManifest.xml에 스토리지

읽기, 쓰기 권한을 설정합니다.

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

Provider을 사용하기 위해서 코틀린(Kotlin)

Class를 생성합니다.

Kotlin File/Class 메뉴를 선택 후

GenericFileProvider Class를 생성합니다.

package com.office.secuex
import androidx.core.content.FileProvider
class GenericFileProvider : FileProvider()

Provider path를 연결하기 위해서 package 이름을 추가하고

탐색기(Explorer)에 사용할 FileProvider을 상속받습니다.

Provider을 연결하기 위한

provider_paths.xml을 생성합니다.

<paths xmlns:android="http://schemas.android.com/apk/res-auto">
    <external-path
        name="external_files"
        path="."/>
</paths>

xml 정보를 입력하고 경로를 확인합니다.

provider을 연결하기 위해서

Manifest.xml 파일 하단에 provider 정보를

입력합니다.

        <provider
            android:authorities="com.office.secuex"
            android:name=".GenericFileProvider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/provider_paths"/>
        </provider>

autorities 속성은 생성한 package 이름으로 변경

name 속성은 생성한 Provider 파일 명

resource 속성은 xml 경로입니다.

 

코틀린(Kotlin) Provider를 설정 후 빌드를

진행하면 정상적으로 오류 없이 빌드됩니다.

오류가 발생할 경우 대부분 provider 속성 오류입니다.

 

다음 시간에는 Provider을 사용해서

파일 리스트를 생성해보겠습니다.

감사합니다.

http://thetechnocafe.com/build-a-file-explorer-in-kotlin-part-1-introduction-and-set-up/

 

Build a File Explorer in Kotlin - Part 1 - Introduction and Set up - TheTechnoCafe

This tutorial series will guide you through building a simple Android File Explorer application in Kotlin. You will develop a file explorer application...

thetechnocafe.com

 

반응형
반응형

블록체인(Blockchain)은 거래 기록이 담긴 블록이

체인처럼 서로 연결되어 있는 구조를  말합니다.

요즘 많은 사람들이 암호화폐에 대해서 관심 있어서

블록체인(Blockchain)은 더욱더 인기가 높아지고 있습니다.

 

오늘은 파이썬(python)을 사용해서 간단한 

블록체인(Blockchain)을 만들어보겠습니다.

먼저 블록체인(Blockchain) 특징을 알아보겠습니다.

블록체인은 3가지 특징이 있습니다.

첫 번째 특징 분산화

블록체인에 저장된 모든 정보가 전체
네트워크의 한 단위로 동작합니다.
중앙 집중식 권한이 없이 모든 노드 간의
정보 공유가 가능합니다.

두 번째 특징 불변성
블록체인의 모든 데이터는 추가 적용됩니다.
데이터를 삭제하지 않으며
과거에 무언가를 수정하려면
새로운 주석 데이터를 추가해야 합니다.

세 번째 특징 분산 원장
블록체인은 공개 또는 비공개가 가능합니다.
하지만 특정 누구에게 속하는 것이
아닌 그룹에만 속합니다.

블록체인(Blockchain)은 기본적으로 Hash를 사용해서

고유성을 유지합니다.

각 블록에는 Previous hash, Current hash를 사용해서

블록 간에 연결을 유지합니다.

파이썬(python)에서 hash를 사용하기 위해서는

hashlib를 import 해줘야 합니다.

hash를 사용할 경우 가장 중요한 내용이 있습니다.

일반적으로 hahs class를 사용해서 update를

할 경우 아래와 같은 error가 발생합니다.

"unicode-objects must be encoded before hashing"

상기 오류는 hash에 사용되는 text 정보를

encode 해줘야 합니다.

먼저 Block Class를 만들어 보겠습니다.

Block Class는 __init__ 함수를 사용해서 index, timestamp

data, previous_hash, hash를 설정합니다.

hash_block() 함수는 블록 정보를 한 번에 출력할 수 있습니다.

hash_block() 함수에서 sha.update를 사용할 경우

입력 text를 encode('utf-8') 함수를 사용해서

encode을 진행해야 오류가 발생하지 않습니다.

create_gensis_block() 함수를 생성합니다.

create_gensis_block() 함수는 초기화 함수로

최초 block을 생성합니다.

블록체인(Blockchain)을 연결하기 위한

next_block() 함수를 정의합니다.

신규 블록을 생성해서 hash 정보에

마지막 블록 hash 정보를 저장합니다.

블록체인(Blockchain)을 생성하기 위해서

최초 블록을 저장합니다.

저장된 블록은 총 20개로 순차적으로

블록을 생성해서 연결합니다.

컴파일 결과 20개의 블록이 순차적으로

연결되어 저장되었습니다.

Hash 정보를 확인하면 중복되지 않는 정보로

고유성을 유지하면서 블록체인(Blockchain)을 연결합니다.

전체 소스 내용

import datetime
import hashlib
from datetime import datetime


class Block:
    def __init__(self, index, timestamp, data, previous_hash):
        self.index = index
        self.timestamp = timestamp
        self.data = data
        self.previous_hash = previous_hash
        self.hash = self.hash_block()
    def hash_block(self):
        sha = hashlib.sha256()
        data = str(self.index) + str(self.timestamp) +  str(self.data) + str(self.previous_hash)
        sha.update(data)
       #sha.update( data.encode('utf-8'))
        return sha.hexdigest()

def create_genesis_block():
    return Block(0, datetime.now(), "Genesis Block", "0")


def next_block(last_block):
    this_index = last_block.index + 1
    this_timestamp = datetime.now()
    this_data = "Block Data :  " + str(this_index)
    this_hash = last_block.hash
    return Block(this_index, this_timestamp, this_data, this_hash)
    
if __name__ == '__main__':
	blockchain = [create_genesis_block()]
    previous_block = blockchain[0]

    num_of_blocks_to_add = 20

    for i in range(0, num_of_blocks_to_add):
        block_to_add = next_block(previous_block)
        blockchain.append(block_to_add)
        previous_block = block_to_add
        print("Block #{} added blockchain".format(block_to_add.index))
        print("Block Data: {}n".format(block_to_add.data))
        print("Block Hash: {}n".format(block_to_add.hash))

 

블록체인(Blockchain)은 매우 복잡한 구조로 동작합니다.

오늘은 간단하게 hash를 사용해서 블록체인(Blockchain) 

개념을 확인했습니다.

파이썬(python)으로 간단하게 구현이 가능하기 때문에

한번 정도 코딩하시면서 공부하는 것을 추천합니다.

감사합니다.

반응형
반응형

파이썬(python)은 복잡한 코드도 간단하게 코딩할 수 있는 정말 좋은 프로그램 언어입니다.

파이썬을 사용하면 인터 프린터 형태로 컴파일되기 때문에 한 개의 변수 형태로 많이 사용합니다.

간단한 코드는 다양한 변수를 사용해소 코드가 가능하지만, 조금씩 변수가 증가하면 매우 복잡해지겠죠.

먼저 간단하게 이름, 주소, 전화 번호를 출력하는 프로그램을 작성해보겠습니다.

def printInfo():
    name = "365talk"
    address = "seoul"
    phone = "010-1234-5678"

    print(f"name : {name}")
    print(f"address : {address}")
    print(f"phone : {phone} ")

name, address, phone 변수를 선언 후 정보를 저장합니다.

print() 함수를 사용해서 변수를 출력합니다.

name, address, phone 모든 내용을 한 번에 확인할 수 있습니다.

그럼 이번에는 변수 한개를 더 추가해보겠습니다.

email 변수를 사용해서 mail 정보를 입력합니다.

def printInfo():
    name = "365talk"
    address = "seoul"
    phone = "010-1234-5678"
    email = "365talk@gmail.com"

    print(f"name : {name}")
    print(f"address : {address}")
    print(f"phone : {phone} ")
    print(f"email : {email}")

email 변수 추가와 동시에 출력하기 위한 print() 정보도 추가합니다.

출력 결과도 동일하게 print()함수를 사용해서 출력할 수 있습니다.

간단한 변수를 여러개 사용할 경우 추가적으로 변수를 선언하면 됩니다.

하지만 변수 개수가 증가할수록 코드 길이가 길어지면서 관리하기가 점점 힘들어집니다.

변수를 혹 배열로 사용할 경우는 변수 관리는 더욱더 복잡해집니다.

 

클래스 구조

파이썬(python)은 이러한 관리 문제를 해결하기 위해서 클래스(Class)를 사용할 수 있습니다.

클래스(Class)는 간단하게 말하면 변수 그룹, 함수 그룹을 모두 하나의 그룹으로 관리할 수 있는 집합 객체입니다.

클래스(Class)를 사용하면 객체를 복사할 수 있기 때문에 배열에 사용하기도 매우 편리합니다.

파이썬(python)에서는 함수와 동일하게 class를 단어를 앞쪽에 선언해서 클래스(Class)를 선언할 수 있습니다.

class DataInfo:
    pass


info = DataInfo()
print(info)
print(type(info))

class DataInfo 객체를 생성했습니다.

DataInfo 객체를 생성하고 출력하면 객체가 생성된 주소 정보를 확인할 수 있습니다.

DataInfo 객체 시작 주소 정보는 0x00001FDA308F7C0 입니다.

DataInfo 클래스에 추가되는 함수, 변수 모두 주소 이후 연속으로 메모리에 할당됩니다.

type() 함수를 사용하면 생성한 클래스(Class) 타입도 확인이 가능합니다.

 

클래스 만들기

처음에 코딩한 변수 출력 부분을 클래스(Class)로 변경해보겠습니다.

class DataInfo:
    def set_DataInfo(self, name, address, phone, email):
        self.name = name
        self.address = address
        self.phone = phone
        self.email = email
    def print(self):
        print(f"print -----------------")
        print(f"name : {self.name}")
        print(f"address : {self.address}")
        print(f"phone : {self.phone} ")
        print(f"email : {self.email}")
        print(f"print END--------------")

파이썬(python)에서 클래스(Class)를 사용하기 위해서는 메서드앞에 self를 반드시 추가해야 합니다.

self는 클래스(Class)에 생성되는 모든 메서드에 포함되어야 합니다.

set_DataInfo() 메서드 사용 시 self에 name, address, phone, email 변수를 선언하고 인자를 저장합니다.

self에 저장된 변수는 print() 함수를 이용해서 각 변수에 접근 후 출력이 가능합니다.

name = "365talk"
address = "seoul"
phone = "010-1234-5678"
email = "365talk@gmail.com"

info = DataInfo()
info.set_DataInfo(name, address, phone, email)
info.print()

info 변수에 DataInfo() 클래스를 할당합니다.

set_DataInfo() 메서드를 사용해서 name, address, phone, email 정보를 저장할 수 있습니다.

클래스(Class) 객체 선언 후 간단하게 print() 메소드를 사용해서 모든 정보를 출력할 수 있습니다.

파이썬(phthon)에서 클래스(Class)를 사용하게 되면 모든 메서드에 self 인자를 무조건 처음에 사용해야 합니다.

self를 사용하지 않으면 컴파일 과정에서 오류가 발생합니다.

파이썬(phthon)에 사용되는 self 인자는 클래스(Class) 내부 인스턴스 객체로 초기 설정값을 저장하고 인스턴스 형태로 접근이 가능합니다.

즉 인스턴스 형태 메서드를 사용하던, 클래스 형태 메서드를 사용하던 모두 하나의 주소 정보에 접근합니다.

조금 어려운 부분이지만, 그냥 간단하게 객체를 관리하는 집주인이라고 생각하시면 됩니다.

 

클래스 초기화 __init__ 메서드

파이썬(phthon) 클래스(Class)에서도 생성자를 사용한 초기화가 가능합니다.

class DataInfo:
    def __init__(self, id):
        self.id = id
        print("Class Init")
    def set_DataInfo(self, name, address, phone, email):
        self.name = name
        self.address = address
        self.phone = phone
        self.email = email
    def print(self):
        print(f"print -----------------")
        print(f"name : {self.name}")
        print(f"address : {self.address}")
        print(f"phone : {self.phone} ")
        print(f"email : {self.email}")
        print(f"id : {self.id}")
        print(f"print END--------------")

생성된 클래스(Class)에서 __init___ 메서드를 사용해서 초기화가 가능합니다.

__init__ 메서드는 객체가 처음 생성되는 시점에 무조건 호출됩니다.

DataInfo 객체를 선언하는 시점에 __init__에 코딩한 print() 함수가 호출되는 것을 확인할 수 있습니다.

파이썬(python) 클래스(Class)에 미리 선언된 메서드는 "__이름__" 형태로 선언되어 있습니다.

파이참을 사용할 경우 메서드를 바로 확인할 수 있기 때문에 다양한 메서드를 확인해보세요.

파이썬(python) 클래스(Class)는 다양한 API 객체로 배포되기 때문에 꼭 알아야 하는 개념입니다.

클래스(Class) 사용 개념이 없을 경우 크롤링, 주식 API 등 복잡한 코드에 접근하기 어렵습니다.

오늘도 열심히 파이썬(Python) 공부하세요.

감사합니다.

 

반응형
반응형

파이썬(python)에서 사용할 수 있는 팁 러닝 라이브러리 파이토치(PyTorch)는 팁 러닝에서 가장 많이 사용되는

신경망(Neural Networks)을 간편하게 변형하면서 활용이 가능합니다.

신경망(Nural Networks)은 피드 포인트 네트워크가 여러개의 레이어를 차례로 통과시킨 다음 마지막으로 출력을 반환하는 기술입니다.

학습 가능한 파라미터 및 가중치를 적용하여 입력 데이터 세트를 반복하면서 손실 계산 후 보정을 거쳐 네트워크의 가중치를 업데이트합니다.

파이토치(PyTorch)는 신경망(Nural Networks) 데이터에 대한 작업을 수행할 수 있는 계층, 모델을 지원합니다.

torch.nn 네임스페이스를 사용해서 신경 네트워크를 구축에 필요한 빌링 블록을 제공합니다.

신경망(Nural Networks)은 CPU 활용보다는 GPU 모델로 사용하는 것을 권장합니다.

GPU를 사용하기 위해서 Torch.cuda 설치 여부를 확인합니다.

evice = 'cuda' if torch.cuda.is_available() else 'cpu'
    print('Using {} device'.format(device))

전 아직 cuda 설치 전이기 때문에 cpu만 사용이 가능합니다.

 

신경망(Nural Nwtworks)를 사용하기 위해서 서브 클래싱을 통한 nn.Module 계층을 초기화가 필요합니다.

def CheckDevice():
    device = 'cuda' if torch.cuda.is_available() else 'cpu'
    print('Using {} device'.format(device))

    model = NeuralNetwork().to(device)
    print(model)

class NeuralNetwork(nn.Module):
    def __init__(self):
        super(NeuralNetwork, self).__init__()
        self.flatten = nn.Flatten()
        self.linear_relu_stack = nn.Sequential(
            nn.Linear(28*28, 512),
            nn.ReLU(),
            nn.Linear(512, 512),
            nn.ReLU(),
            nn.Linear(512, 10),
            nn.ReLU()
        )

    def forward(self, x):
        x = self.flatten(x)
        logits = self.linear_relu_stack(x)
        return logits

nn.Module 하위 클래스는 forward 메서드의 입력 데이터에 대한 작업을 구현했습니다.

클래스를 사용한 인스턴스를 만들고 device 정보를 출력했습니다.

__init__에 정의된 정보가 device에 저장되어 출력됩니다.

forward는 백그라운드 작업으로 진행되기 때문에 model.forward()를 직접 호출할 필요가 없습니다.

X = torch.rand(1, 28, 28, device=device)
    logits = model(X)
    pred_probab = nn.Softmax(dim=1)(logits)
    y_pred = pred_probab.argmax(1)
    print(f"Predicted class: {y_pred}")

정의된 클래스에 원시 예측 값이 있는 10차원 텐서를 설정하기 위해서, nn.Softmax 모듈의 인스턴스를 사용해서 예측 확률을 확인합니다.

 

파이 토치 신경망 모델 레이어

모델의 레이어를 구분하기 위해서 간단한 28 x 28인 이미지 3개의 샘플을 저장합니다.

def Modellayer():
    input_image = torch.rand(3, 28, 28)
    print(input_image.size())

3개의  28 x 28 이미지를 확인할 수 있습니다.

nn.Flatten 레이어를 초기화하여 각 2D 28 x 28 이미지를 784 픽셀 값의 연속 배열로 변환합니다.

def Modellayer():
    input_image = torch.rand(3, 28, 28)
    print(input_image.size())

    flatten = nn.Flatten()
    flat_image = flatten(input_image)
    print(flat_image.size())

3개의 배열이 784 연속 배열로 변경되었습니다.

nn.Linear은 선형 레이어를 구현할 수 있습니다.

def Modellayer():
    input_image = torch.rand(3, 28, 28)
    print(input_image.size())

    flatten = nn.Flatten()
    flat_image = flatten(input_image)
    print(flat_image.size())

    layer1 = nn.Linear(in_features=28 * 28, out_features=20)
    hidden1 = layer1(flat_image)
    print(hidden1.size())

hidden1 선형 레이어를 생성했습니다.

nn.ReLU은 입력과 출력 사이에 복잡한 매핑 비선형성을 사용할 수 있습니다.

선형 레이어 사이에 nn.ReLU를 사용해서 비선형성을 실행합니다.

def Modellayer():
    input_image = torch.rand(3, 28, 28)
    print(input_image.size())

    flatten = nn.Flatten()
    flat_image = flatten(input_image)
    print(flat_image.size())

    layer1 = nn.Linear(in_features=28 * 28, out_features=20)
    hidden1 = layer1(flat_image)
    print(hidden1.size())

    print(f"Before ReLU: {hidden1}\n\n")
    hidden1 = nn.ReLU()(hidden1)
    print(f"After ReLU: {hidden1}")

nn.Sequential은 모듈의 순서가 지정된 컨테이너를 생성할 수 있습니다.

정의된 데이터와 동일한 순서로 모든 모듈에 전달됩니다.

순차 컨테이너는 빠른 네트워크를 구성하기 위해서 사용됩니다.

seq_modules = nn.Sequential(
    flatten,
    layer1,
    nn.ReLU(),
    nn.Linear(20, 10)
    )
    input_image = torch.rand(3,28,28)
    logits = seq_modules(input_image)
    print(logits)

nn.Softmax는 원시 값인 로짓을 반환합니다.

로짓은 각 클래스에 대한 모델의 확률을 나타내는 값[0,1]으로 지정됩니다.

매개변수는 값의 합이 1이 되어야 차원을 나타냅니다.

    softmax = nn.Softmax(dim=1)
    pred_probab = softmax(logits)

    print(pred_probab)

 

파이 토치 신경망 모데 매개변수

신경망에 사용되는 레이어는 매개변수화되어 있어 접근이 가능합니다.

서브 클래싱 된 nn.Module은 객체 내부에 정의된 모든 필드를 자동으로 추적하고 모델 parameters() 또는 named_parameters() 메서드를 사용하여 모든 매개변수에 액세스 할 수 있습니다.

    print("Model structure: ", model, "\n\n")

    for name, param in model.named_parameters():
        print(f"Layer: {name} | Size: {param.size()} | Values : {param[:2]} \n")

처음 구현한 model에 추가 코드를 적용해서 매개변수를 확인했습니다.

파이토치(PyTorch) 신경망(Nural Networks)은 복잡한 정보를 클래스를 사용해서 다양한 구성이 가능합니다.

모델 레이어를 사용해서 가중치를 높이면서 정확한 데이터를 확보할 수 있습니다.

감사합니다.

반응형
반응형

파이썬(python)에서 사용할 수 있는 파이토치(PyTorch)는 간단하게 딥 러닝을 구현할 수 있는 좋은 라이브러리입니다.

오늘은 파이토치(PyTorch)에서 딥 러닝에서 많이 사용되는 데이터 정보를 관리할 수 있는 데이터 세트(Dataset) 및 데이터 로더(Dataloader)에 대해서 알아보겠습니다.

배열과 같은 데이터 정보는 단순한 형태를 사용하기 편리하지만, 정보가 증가하면 유지 관리하기 어렵습니다.

데이터 세트(Dataset)는 가독성을 높이면서 데이터를 쉽게 액세스 할 수 있도록 도와줍니다.

파이토치(PyTorch) 데이터 세트(Dataset)를 사용하기 위해서는 torchvision 패키지를 인스톨해야 합니다.

torchvision 패키지 인스톨을 진행하면 java SDK를 업데이트합니다.

설치 화면에서 설치를 클릭해주세요.

 

데이터 세트(Dataset)는 기본적으로 사용할 수 있는 데이터 정보를 다운로드하여 저장할 수 있습니다.

training_data = datasets.FashionMNIST(
        root="data",
        train=True,
        download=True,
        transform=ToTensor()
    )

FashionMNIST 메서드를 사용해서 이미지 정보를 training_data에 저장합니다.

FashionMNIST 메서드 root는 테스트 데이터 저장 경로입니다.

train은 데이터 세트 지정 정보입니다.

download는 데이터 다운로드 설정 정보입니다.

transform은 레이블 변환 지정입니다.

코드를 실행하면 출력 창에서 이미지 다운로드 화면을 확인할 수 있습니다.

training_data에 저장된 데이터 세트(Dataset) 정보를 출력해보겠습니다.

def showimage():
    training_data = datasets.FashionMNIST(
        root="data",
        train=True,
        download=True,
        transform=ToTensor()
    )
    labels_map = {
        0: "T-Shirt",
        1: "Trouser",
        2: "Pullover",
        3: "Dress",
        4: "Coat",
        5: "Sandal",
        6: "Shirt",
        7: "Sneaker",
        8: "Bag",
        9: "Ankle Boot",
    }
    figure = plt.figure(figsize=(8, 8))
    cols, rows = 3, 3
    for i in range(1, cols * rows + 1):
        sample_idx = torch.randint(len(training_data), size=(1,)).item()
        img, label = training_data[sample_idx]
        figure.add_subplot(rows, cols, i)
        plt.title(labels_map[label])
        plt.axis("off")
        plt.imshow(img.squeeze(), cmap="gray")
    plt.show()

배열에 저장된 9개의 이미지 정보를 기준으로 데이터 세트(Dataset)에서 이미지를 확인 후 matplotlib 패키지 plt를 사용해서 이미지로 출력합니다.

출력 결과 9개의 이미지가 순차적으로 출력됩니다.

데이터 세트(Dataset)는 예제 정보를 다운로드할 수 있어 간단하게 이미지 관련 딥러닝을 실행할 수 있습니다.

 

데이터 세트(Dataset)는 배열처럼 사용하는 방법보다는 클래스로 구현하면 더욱더 쉽게 사용할 수 있습니다.

기복적으로 __init__, __len__, __getitem__ 세 가지를 함수를 추가 구현할 수 있습니다.

class CustomImageDataset(Dataset):
    def __init__(self, annotations_file, img_dir, transform=None, target_transform=None):
        self.img_labels = pd.read_csv(annotations_file)
        self.img_dir = img_dir
        self.transform = transform
        self.target_transform = target_transform

    def __len__(self):
        return len(self.img_labels)

    def __getitem__(self, idx):
        img_path = os.path.join(self.img_dir, self.img_labels.iloc[idx, 0])
        image = read_image(img_path)
        label = self.img_labels.iloc[idx, 1]
        if self.transform:
            image = self.transform(image)
        if self.target_transform:
            label = self.target_transform(label)
        return image, label

클래스에 사용할 수 있는 기본 함수는 자동 생성되기 때문에 필요한 부분을 추가 구현할 수 있습니다.

__init__ 함수는 데이터 세트(Dataset) 객체를 인스턴스화 할 때 한번 실행됩니다.

기본적으로 초기화에 필요한 정보를 입력할 수 있습니다.

__len__ 함수는 데이터 세트(Dataset) 객체 개수를 반환합니다.

__getitem__ 함수는 선택한 인덱스의 데이터 정보를 로드하여 반환합니다.

변환 정보는 처음 배운 텐서로 변환되어 사용할 수 있습니다.

 

데이터 로더(Dataloader)는 데이터 세트 클래스의 확장 형태로 간단하게 데이터 세트를 접근할 수 있습니다.

간단하게 말해서 데이터 로더(Dataloader)는 데이터 세트의 복잡성을 간단한 API로 추상화한 클래스입니다.

데이터 로더(Dataloader)를 사용하기 위해서 torch.utils.data 패키지를 설치합니다.

def DataLoaderEx():
    training_data = datasets.FashionMNIST(
        root="data",
        train=True,
        download=True,
        transform=ToTensor()
    )
    train_dataloader = DataLoader(training_data, batch_size=64, shuffle=True)

    train_features, train_labels = next(iter(train_dataloader))
    print(f"Feature batch shape: {train_features.size()}")
    print(f"Labels batch shape: {train_labels.size()}")
    img = train_features[1].squeeze()
    label = train_labels[1]
    plt.imshow(img, cmap="gray")
    plt.show()
    print(f"Label: {label}")

데이터 로더(Dataloader)를 로드된 데이터 세트를 생성자에 대입만 하면 바로 사용이 가능합니다.

데이터 로더(Dataloader)는 배열 사용과 동일하게 인덱스를 입력하면 바로 이미지를 확인할 수 있습니다.

데이터 로더(Dataloader) 인덱스 정보를 변경하면 다음 이미지를 확인할 수 있습니다.

파이토치(PyTorch)  데이터 세트(Dataset) 및 데이터 로더(Dataloader)는 이미지 정보와 같은 복잡한 정보를 누구가 쉽게 사용할 수 있도록 구현된 객체입니다.

기본 정보를 다운로드하여 객체에 저장하기 때문에 별도 이미지를 찾을 필요가 없습니다.

딥 러닝은 코드 보다도 알고리즘이 중요하기 때문에 코드를 매우 단순화할 수 있는 좋은 패키지라고 생각됩니다.

감사합니다.

https://pytorch.org/tutorials/beginner/basics/quickstart_tutorial.html

 

Quickstart — PyTorch Tutorials 1.9.0+cu102 documentation

Note Click here to download the full example code Learn the Basics || Quickstart || Tensors || Datasets & DataLoaders || Transforms || Build Model || Autograd || Optimization || Save & Load Model Quickstart This section runs through the API for common task

pytorch.org

 

반응형

+ Recent posts