파싱할 xml은 다음과 같습니다.

ml_string = '''<?xml version="1.0"?> 
<data> 
  <tool name="Keras"> 
      <rank>1</rank> 
      <content>good</content>
      <merge name="TensorFlow" year="2020"/>
  </tool> 
  <tool name="TensorFlow"> 
      <rank>1</rank>
      <content>nice</content>
  </tool>
  
  <tool2 name="PyTorch"> 
      <rank>2</rank> 
      <content>research</content>
  </tool2> 
  <tool2 name="MXNet"> 
      <rank>3</rank> 
      <content>well</content>
  </tool2> 
</data> 
'''

ElementTree를 통해 xml 파일을 지정하고 root에 접근하는 방법은 다음과 같습니다.

tree = elemTree.parse('ml.xml')
root = tree.getroot()

* 여기서는 예제를 위해 string을 사용하므로 다음을 사용합니다. 파일을 통한 파싱은 위 코드로 해야합니다.
  아래 코드는 관련 없습니다.

root = ET.fromstring(ml_string)

 

태그와 태그가 가지고 있는 속성은 다음과 같이 확인할 수 있습니다.

print(root.tag, root.attrib)
  • data {}

 

ElementTree에서는 대표적으로 find(), findall(), iter() 함수를 많이 사용합니다.

find()

print(root.find('tool'))
print(root.find('tool').tag, '|', root.find('tool').attrib)

# 하위 태그를 탐색할 수 있습니다.
for child in root.find('tool'):
    print(child.tag, child.attrib)
  • <Element 'tool' at 0x000001E489FB5AE8>
    tool | {'name': 'Keras'}
    rank {}
    content {}
    merge {'name': 'TensorFlow', 'year': '2020'}
  • root.find('tag_name')은 여러 개의 태그 중에서 가장 첫 번째 태그를 가져옵니다.
  • for-loop를 통해 하위 태그를 확인하고 있습니다.

 

findall()

print(root.findall('tool'))

# <tool/> 태그를 전부 탐색할 수 있습니다.
for root_e in root.findall('tool'):
    print(root_e.tag, root_e.attrib)
  • [<Element 'tool' at 0x000001E489FB5AE8>, <Element 'tool' at 0x000001E489FBE228>]
    tool {'name': 'Keras'}
    tool {'name': 'TensorFlow'}
  • 원하는 태그를 전부 찾아서 리스트 형태로 얻을 수 있습니다. 하지만 하위 태그는 찾아주지 않습니다.

iter()

# <tool2/> 태그를 전부 탐색할 수 있습니다.
for root_e in root.iter('tool2'):
    print(root_e.tag, root_e.attrib)
  • tool2 {'name': 'PyTorch'}
    tool2 {'name': 'MXNet'}
  • find, findall과 다르게 상위 또는 하위 태그를 전부 찾아줍니다.

 

다음은 원하는 두 가지 태그를 찾고, 태그의 text를 변경하여 저장하는 것까지의 예제 코드입니다.

def parse_xml(xml_list):
    for xml_name in xml_list:
        xml = './' + xml_name
        attached_name = 'abc'
        
        tree = elemTree.parse(gml)
        root = tree.getroot()
        
        # 두 개 태그의 text를 수정한다고 가정합니다.
        for attr1, attr2 in zip(root.iter('attr_1'), root.iter('attr_2')):
            attr1_newtext = attached_name + attr1.text
            attr2_newtext = attached_name + attr2.text
            
            attr1.text = attr1_newtext
            attr2.text = attr2_newtext
        
        # 수정한 xml 파일을 저장합니다.
        tree.write('./' + xml_name)

 

파싱할 xml에 namespace가 존재하는 경우

간혹 xml에 다음과 같이 namespace가 존재하는 경우가 있다.

다음과 같이 namespace를 등록하지 않으면, ElementTree가 자동으로 ns0, ns1, ...으로 등록하기 때문에 주의해야 한다.

ET.register_namespace("gml", "http://www.opengis.net/gml")
ET.register_namespace("bldg", "http://www.opengis.net/citygml/building/2.0")
ET.register_namespace("app", "http://www.opengis.net/citygml/appearance/2.0")
ET.register_namespace("core", "http://www.opengis.net/citygml/2.0")

깃허브의 저장소에 100MB 이상의 파일을 push 하게 되면 에러가 발생하게 됩니다.

이러한 대용량 파일을 업로드하기 위해서 git-lfs 를 설치해주면 된다.


1. 먼저 다음 사이트에서 git-lfs를 다운로드한다.

https://git-lfs.github.com/

2. 'git lfs install'을 입력한다.

Updated git hooks.
Git LFS initialized.

3. 'git lfs track "*.확장자명"' 을 입력한다.

예를 들어, 대용량의 json 파일을 업로드하길 원한다면 다음과 같이 입력하면 되겠다.

  • git lfs track "*.json"

아마 위의 명령어를 실행하였다면, 해당 폴더에 .gitattributes 파일이 생겼을 것이다.

4. 이 다음으로는 기존 push 하는 과정과 동일하다.

  • git add .
  • git commit -m "message"
  • git push origin master

5. 위와 같은 과정을 거쳤음에도 불구하고 또 다시 에러가 뜬다면, 이미 이전에 대용량 파일을
    업로드한 로그가 남아있어서 그렇다.

5-1. 먼저 다음 사이트에서 .jar file을 다운로드한다.

https://rtyley.github.io/bfg-repo-cleaner/

5-2. 다음 명령어를 실행한다.

  • java -jar bfg-x.xx.xx.jar --strip-blobs-bigger-than 100M

xx는 본인이 다운로드받은 버전을 입력해주면 된다.

신경망을 그려주는 도구는 라이브러리도 있고 여러가지 사이트가 존재하지만,

이 글에서 링크된 사이트가 우선적으로 되게 간편하게 사용할 수 있는 사이트인 것 같다.

기본적으로 FCNN, LeNet, AlexNet 구조에 대해서만 그릴 수 있다.

http://alexlenail.me/NN-SVG/index.html
 

NN SVG

 

alexlenail.me

 

간혹가다 nvidia driver만 삭제되는 경우가 발생한다. 

나의 경우는 cuda, cuDnn 은 살아있어도, 계속 nvidia가 날려져서 다시 깔고 있었는데, 알고보니 내부적으로 충돌로 인해 이를 삭제하는 것이라고 한다.

따라서 nouveau를 비활성화해주면 이런 경우가 없어진다고 한다.


1. 다음 파일을 찾아간다.

/etc/modprobe.d/blacklist-nouveau.conf

2. 다음 내용을 추가합니다.

blacklist nouveau
options nouveau modeset=0

3. 커널에 입력시켜줍니다.

sudo update-initramfs -u

4. 재부팅합니다.

sudo reboot

 

다음과 같이 사용한다.

import numpy as np
x = np.array([1, 4, 5, 1000, 100, 3, 10, 2])
print(x)
print('----------------------')
print('partition',np.partition(x, -3))
print('partition',np.partition(x, -1))
print(np.argpartition(x, -3))
print(x[np.argpartition(x, -3)])
print('----------------------')
print('partition', np.partition(x, 3))
print(np.argpartition(x, 3))
print(x[np.argpartition(x, 3)])
print('----------------------')
print(np.partition(x, (1, 2)))
print(np.argpartition(x, (1, 3)))
print(x[np.argpartition(x, (1, 5))])

츌력 결과

np.partition에 대해서 설명하면, np.partition(np.array(), k-th)로 사용하는데

np.partition(~, 2)와 같은 경우는 리스트에서 순서 상관없이 작은 숫자 2개를 뽑아 왼쪽으로 놓겠다는 의미

np.partition(~, -2)와 같은 경우는 리스트에서 순서 상관없이 큰 값 2개를 뽑아 오른쪽으로 놓겠다는 의미이다.

np.argpartition은 partition과 같고, index를 리턴한다.

 

+ 틀리면 댓글 부탁드립니다.